diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 0337a51f1..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: A generic bug Report -about: Create a bug report to help us improve ArrayFire -title: "[BUG]" -labels: 'Bug' -assignees: '' ---- - - -Description -=========== - - -Reproducible Code and/or Steps ------------------------------- - - -System Information ------------------- - - -Checklist ---------- - -- [ ] Using the latest available ArrayFire release -- [ ] GPU drivers are up to date diff --git a/.github/ISSUE_TEMPLATE/build_error.md b/.github/ISSUE_TEMPLATE/build_error.md deleted file mode 100644 index f13c9172b..000000000 --- a/.github/ISSUE_TEMPLATE/build_error.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Build Error -about: Create a report for errors during the crate build -title: "[Build]" -labels: 'Bug,Build' -assignees: '9prady9' ---- - -Description -=========== - - -Build Environment ------------------ -Compiler version: -Operating system: -Build environment: - -Error Log ---------- - -``` - -``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 0efe0ffb5..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: Feature Request -about: Suggest a new idea for Rust wrapper of ArrayFire -title: 'Feature' -labels: 'Feature' -assignees: '9prady9' - ---- - -Description -=========== - diff --git a/.github/ISSUE_TEMPLATE/performance_issue.md b/.github/ISSUE_TEMPLATE/performance_issue.md deleted file mode 100644 index df002a5aa..000000000 --- a/.github/ISSUE_TEMPLATE/performance_issue.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Performance Issue -about: For Issues related to lackluster performance -title: "[Perf]" -labels: 'Bug,Upstream' -assignees: '9prady9' - ---- - -Description -=========== - - - - - -Reproducible Code ------------------ - - -System Information ------------------- -ArrayFire Version: -Device: -Operating System: -Driver version: - -Checklist ---------- -- [ ] I have read [timing ArrayFire C++ API](http://arrayfire.org/docs/timing.htm) diff --git a/.github/PULL_REQUEST_TEMPLATE/documentation.md b/.github/PULL_REQUEST_TEMPLATE/documentation.md deleted file mode 100644 index 9531979da..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/documentation.md +++ /dev/null @@ -1,20 +0,0 @@ - - -Description ------------ - -Fixes: # ... - -Checklist ---------- -- [ ] Rebased on latest master -- [ ] Documentation Generation Successful -- [ ] Documentation Tests Pass diff --git a/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md b/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md deleted file mode 100644 index fb83f2360..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md +++ /dev/null @@ -1,36 +0,0 @@ - - - -Description ------------ - -Fixes: # ... - -Changes to Users ----------------- - - -Checklist ---------- - -- [ ] Rebased on latest master -- [ ] Code compiles -- [ ] Tests pass -- [ ] Functions documented diff --git a/.github/PULL_REQUEST_TEMPLATE/new_example.md b/.github/PULL_REQUEST_TEMPLATE/new_example.md deleted file mode 100644 index f823278e6..000000000 --- a/.github/PULL_REQUEST_TEMPLATE/new_example.md +++ /dev/null @@ -1,14 +0,0 @@ - - -Description ------------ - - -Checklist ---------- -- [ ] Rebased on latest master -- [ ] Code compiles diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 801afa712..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,114 +0,0 @@ -on: - push: - branches: - - master - pull_request: - branches: - - master - -name: ci - -jobs: - build_test: - name: Build and Test Wrapper - runs-on: ubuntu-18.04 - env: - AF_VER: 3.8.0 - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Rust Toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Cache ArrayFire - uses: actions/cache@v1 - id: arrayfire - with: - path: afbin - key: ${{ runner.os }}-af-${{ env.AF_VER }} - - - name: Download ArrayFire - # Only download and cache arrayfire if already not found - if: steps.arrayfire.outputs.cache-hit != 'true' - run: | - wget --quiet http://arrayfire.s3.amazonaws.com/${AF_VER}/ArrayFire-v${AF_VER}_Linux_x86_64.sh - chmod +x ./ArrayFire-v${AF_VER}_Linux_x86_64.sh - mkdir afbin - ./ArrayFire-v${AF_VER}_Linux_x86_64.sh --skip-license --exclude-subdir --prefix=./afbin - rm ./afbin/lib64/libcu*.so* - rm ./afbin/lib64/libafcuda*.so* - rm ./ArrayFire-v${AF_VER}_Linux_x86_64.sh - - - name: Build and Run Tests - run: | - export AF_PATH=${GITHUB_WORKSPACE}/afbin - export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${AF_PATH}/lib64 - echo "Using cargo version: $(cargo --version)" - cargo build --all --all-features - cargo test --no-fail-fast --all-features - - format: - name: Format Check - runs-on: ubuntu-18.04 - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Rust Toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - components: rustfmt - - name: Run rust fmt tool - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - clippy: - name: Clippy Lints - runs-on: ubuntu-18.04 - env: - AF_VER: 3.8.0 - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - - name: Setup Rust Toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - components: clippy - - - name: Cache ArrayFire - uses: actions/cache@v1 - id: arrayfire - with: - path: afbin - key: ${{ runner.os }}-af-${{ env.AF_VER }} - - - name: Download ArrayFire - # Only download and cache arrayfire if already not found - if: steps.arrayfire.outputs.cache-hit != 'true' - run: | - wget --quiet http://arrayfire.s3.amazonaws.com/${AF_VER}/ArrayFire-v${AF_VER}_Linux_x86_64.sh - chmod +x ./ArrayFire-v${AF_VER}_Linux_x86_64.sh - mkdir afbin - ./ArrayFire-v${AF_VER}_Linux_x86_64.sh --skip-license --exclude-subdir --prefix=./afbin - rm ./afbin/lib64/libcu*.so* - rm ./afbin/lib64/libafcuda*.so* - rm ./ArrayFire-v${AF_VER}_Linux_x86_64.sh - - - name: Run clippy tool - env: - AF_PATH: ${{ github.workspace }}/afbin - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml deleted file mode 100644 index 7cba9dce8..000000000 --- a/.github/workflows/security.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: Security -on: - schedule: - - cron: '0 0 * * 0' -jobs: - audit: - name: Dependencies Security Audit - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/audit-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 39a9fa998..000000000 --- a/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Compiled files -*.o -*.so -*.rlib -*.dll - -# Executables -*.exe - -# Generated by Cargo -/target/ -Cargo.lock - -# ide files -.idea/ -.vscode/ - -#example downloads -data/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 6515f7852..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "arrayfire"] - path = arrayfire - url = https://github.com/arrayfire/arrayfire diff --git a/.lock b/.lock new file mode 100755 index 000000000..e69de29bb diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt new file mode 100644 index 000000000..af77776cc --- /dev/null +++ b/COPYRIGHT.txt @@ -0,0 +1,45 @@ +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff, FiraSans-Medium.woff): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif Pro (SourceSerifPro-Regular.ttf.woff, + SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff): + + Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with + Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of + Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerifPro-LICENSE.txt. + +This copyright file is intended to be distributed with rustdoc output. diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 4c10f777f..000000000 --- a/Cargo.toml +++ /dev/null @@ -1,109 +0,0 @@ -[package] -edition = "2018" -name = "arrayfire" -description = "ArrayFire is a high performance software library for parallel computing with an easy-to-use API. Its array based function set makes parallel programming simple. ArrayFire's multiple backends (CUDA, OpenCL and native CPU) make it platform independent and highly portable. A few lines of code in ArrayFire can replace dozens of lines of parallel computing code, saving you valuable time and lowering development costs. This crate provides Rust bindings for ArrayFire library." -version = "3.8.0" -documentation = "http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html" -homepage = "https://github.com/arrayfire/arrayfire" -repository = "https://github.com/arrayfire/arrayfire-rust" -authors = ["Pradeep Garigipati ", "Jason Ramapuram "] -readme = "./README.md" -keywords = ["CUDA", "OpenCL", "ArrayFire", "Compute"] -license = "BSD-3-Clause" -build = "build.rs" -exclude = [ - "arrayfire/*", -] - -[workspace] -members = [ - "cuda-interop", - "opencl-interop", -] - -[lib] -name = "arrayfire" -path = "src/lib.rs" - -[package.metadata.docs.rs] -rustdoc-args = [ "--html-in-header", "./scripts/mathjax.script", ] - -[features] -algorithm = [] -arithmetic = [] -blas = [] -data = [] -indexing = [] -graphics = [] -image = [] -lapack = [] -ml = [] -macros = [] -random = [] -signal = [] -sparse = [] -statistics = [] -vision = [] -default = ["algorithm", "arithmetic", "blas", "data", "indexing", "graphics", "image", "lapack", -"ml", "macros", "random", "signal", "sparse", "statistics", "vision"] -afserde = ["serde"] - -[dependencies] -libc = "0.2" -num = "0.4.0" -lazy_static = "1.0" -half = { version = "2.2.1" , features = ["num-traits"] } -serde = { version = "1.0", features = ["derive"], optional = true } - -[dev-dependencies] -half = { version = "2.2.1" , features = ["num-traits"] } -serde_json = "1.0" -bincode = "1.3" -mnist = {version="0.5.0", features = ["download"]} - -[build-dependencies] -serde_json = "1.0" -serde_derive = "1.0" -serde = "1.0" -rustc_version = "0.3.3" - -[[example]] -name = "helloworld" -path = "examples/helloworld.rs" - -[[example]] -name = "unified" -path = "examples/unified.rs" - -[[example]] -name = "pi" -path = "examples/pi.rs" - -[[example]] -name = "snow" -path = "examples/snow.rs" - -[[example]] -name = "histogram" -path = "examples/histogram.rs" - -[[example]] -name = "acoustic_wave" -path = "examples/acoustic_wave.rs" - -[[example]] -name = "conway" -path = "examples/conway.rs" - -[[example]] -name = "fft" -path = "examples/fft.rs" - -[[example]] -name = "using_half" -path = "examples/using_half.rs" - -[[example]] -name = "neural_network" -path = "examples/neural_network.rs" - diff --git a/FiraSans-LICENSE.txt b/FiraSans-LICENSE.txt new file mode 100644 index 000000000..d444ea92b --- /dev/null +++ b/FiraSans-LICENSE.txt @@ -0,0 +1,94 @@ +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/FiraSans-Medium.woff b/FiraSans-Medium.woff new file mode 100644 index 000000000..7d742c5fb Binary files /dev/null and b/FiraSans-Medium.woff differ diff --git a/FiraSans-Regular.woff b/FiraSans-Regular.woff new file mode 100644 index 000000000..d8e0363f4 Binary files /dev/null and b/FiraSans-Regular.woff differ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 84eb63a24..000000000 --- a/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2015, ArrayFire -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of arrayfire_rust nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/LICENSE-APACHE.txt b/LICENSE-APACHE.txt new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/LICENSE-APACHE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSE-MIT.txt b/LICENSE-MIT.txt new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/LICENSE-MIT.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 178189c43..000000000 --- a/README.md +++ /dev/null @@ -1,131 +0,0 @@ -[![ci][19]][16] [![docs][18]][3] [![book][22]][21] [![slack][17]][4] [![github-discussions][20]][5] - -# ArrayFire Rust Bindings - -[ArrayFire][1] is a high performance library for parallel computing with an easy-to-use API. It -enables users to write scientific computing code that is portable across CUDA, OpenCL and CPU -devices. This project provides Rust bindings for the ArrayFire library. Given below table shows -the rust bindings compatability with ArrayFire. If you find any bugs, please report them [here][2]. - -| arrayfire-rust | ArrayFire | -|:--------------:|:---------:| -| M.m.p1 | M.m.p2 | - -Only, Major(M) & Minor(m) version numbers need to match. *p1* and *p2* are patch/fix updates for -`arrayfire-rust` & `ArrayFire` respectively, and they don't need to match. - -## Supported platforms - -Linux, Windows and OSX. Rust 1.31 or newer is required. - -## Use from Crates.io [![][6]][7] [![][8]][9] - -To use the rust bindings for ArrayFire from crates.io, the following requirements are to be met first. - -1. [Download and install ArrayFire binaries][10] based on your operating system. Depending on the - method of your installation for Linux, steps (2) & (3) may not be required. If that is the case, - proceed to step (4) directly. -2. Set the evironment variable `AF_PATH` to point to ArrayFire installation root folder. -3. Make sure to add the path to lib files to your path environment variables. - - On Linux: do `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib64` - - On OSX: do `export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$AF_PATH/lib` - - On Windows: Add `%AF_PATH%\lib` to your PATH environment variable. -4. Add `arrayfire = "3.8"` to the dependencies section of your project's Cargo.toml file. - Make sure to change the version to latest available. - -Once step (4) is over, you should be able to use ArrayFire in your Rust project. If you find any -bugs, please report them [here][2]. - -## Build from Source - -Edit [build.conf](build.conf) to modify the build flags. The structure is a simple JSON blob. -Currently Rust does not allow key:value pairs to be passed from the CLI. To use an existing -ArrayFire installation modify the first three JSON values. You can install ArrayFire using -one of the following two ways. - -- [Download and install binaries][10] -- [Build and install from source][1] - -To build arrayfire submodule available in the rust wrapper repository, you have to do the following. - -```bash -git submodule update --init --recursive -cargo build // use --all to build all crates in the workspace -``` -This is recommended way to build Rust wrapper since the submodule points to the most compatible -version of ArrayFire the Rust wrapper has been tested with. You can find the ArrayFire dependencies below. - -- [Linux][11] -- [OSX][12] -- [Windows][13] - -## Example - -```rust -let num_rows: u64 = 5; -let num_cols: u64 = 3; -let dims = Dim4::new(&[num_rows, num_cols, 1, 1]); -let a = randu::(dims); -af_print!("Create a 5-by-3 matrix of random floats on the GPU", a); -``` - -### Sample output - -```bash -~/p/arrayfire_rust> cargo run --example helloworld -... -Create a 5-by-3 matrix of random floats on the GPU -[5 3 1 1] - 0.7402 0.4464 0.7762 - 0.9210 0.6673 0.2948 - 0.0390 0.1099 0.7140 - 0.9690 0.4702 0.3585 - 0.9251 0.5132 0.6814 -... -``` - -### Troubleshooting - -If the build command fails with undefined references errors even after taking care of environment -variables, we recommend doing a `cargo clean` and re-running `cargo build` or `cargo test`. - -You can also use some environment variables mentioned in our [book][23], such as `AF_PRINT_ERRORS` -to print more elaborate error messages to console. - -## Acknowledgements - -The ArrayFire library is written by developers at [ArrayFire][14] LLC with [contributions][15] -from several individuals. The developers at ArrayFire LLC have received partial financial support -from several grants and institutions. Those that wish to receive public acknowledgement are listed -below: - -### Grants - -This material is based upon work supported by the DARPA SBIR Program Office under Contract Numbers -W31P4Q-14-C-0012 and W31P4Q-15-C-0008. Any opinions, findings and conclusions or recommendations -expressed in this material are those of the author(s) and do not necessarily reflect the views of -the DARPA SBIR Program Office. - -[1]: https://github.com/arrayfire/arrayfire -[2]: https://github.com/arrayfire/arrayfire-rust/issues -[3]: http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html -[4]: https://join.slack.com/t/arrayfire-org/shared_invite/MjI4MjIzMDMzMTczLTE1MDI5ODg4NzYtN2QwNGE3ODA5OQ -[5]: https://github.com/arrayfire/arrayfire-rust/discussions -[6]: http://meritbadge.herokuapp.com/arrayfire -[7]: https://crates.io/crates/arrayfire -[8]: https://docs.rs/arrayfire/badge.svg -[9]: https://docs.rs/arrayfire -[10]: https://arrayfire.com/download -[11]: https://github.com/arrayfire/arrayfire/wiki/Build-Instructions-for-Linux -[12]: https://github.com/arrayfire/arrayfire/wiki/Build-Instructions-for-OSX -[13]: https://github.com/arrayfire/arrayfire/wiki/Build-Instructions-for-Windows -[14]: https://arrayfire.com/ -[15]: https://github.com/arrayfire/arrayfire_rust/graphs/contributors -[16]: https://github.com/arrayfire/arrayfire-rust/actions?workflow=CI -[17]: https://img.shields.io/badge/arrayfire-community-e69138?logo=slack -[18]: https://img.shields.io/badge/arrayfire-Docs-blue?logo=readthedocs -[19]: https://github.com/arrayfire/arrayfire-rust/workflows/ci/badge.svg?event=push -[20]: https://img.shields.io/badge/GitHub-Discussions-orange -[21]: http://arrayfire.org/arrayfire-rust/book/index.html -[22]: https://img.shields.io/badge/arrayfire-mdbook-073763?logo=readthedocs -[23]: http://arrayfire.org/arrayfire-rust/book/configuring_arrayfire_environment.html diff --git a/SourceCodePro-LICENSE.txt b/SourceCodePro-LICENSE.txt new file mode 100644 index 000000000..07542572e --- /dev/null +++ b/SourceCodePro-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/SourceCodePro-Regular.woff b/SourceCodePro-Regular.woff new file mode 100644 index 000000000..557667090 Binary files /dev/null and b/SourceCodePro-Regular.woff differ diff --git a/SourceCodePro-Semibold.woff b/SourceCodePro-Semibold.woff new file mode 100644 index 000000000..ca972a11d Binary files /dev/null and b/SourceCodePro-Semibold.woff differ diff --git a/SourceSerifPro-Bold.ttf.woff b/SourceSerifPro-Bold.ttf.woff new file mode 100644 index 000000000..ca254318f Binary files /dev/null and b/SourceSerifPro-Bold.ttf.woff differ diff --git a/SourceSerifPro-It.ttf.woff b/SourceSerifPro-It.ttf.woff new file mode 100644 index 000000000..a287bbe6e Binary files /dev/null and b/SourceSerifPro-It.ttf.woff differ diff --git a/SourceSerifPro-LICENSE.md b/SourceSerifPro-LICENSE.md new file mode 100644 index 000000000..22cb755f2 --- /dev/null +++ b/SourceSerifPro-LICENSE.md @@ -0,0 +1,93 @@ +Copyright 2014-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/SourceSerifPro-Regular.ttf.woff b/SourceSerifPro-Regular.ttf.woff new file mode 100644 index 000000000..a3d55cfdf Binary files /dev/null and b/SourceSerifPro-Regular.ttf.woff differ diff --git a/af_cuda_interop/all.html b/af_cuda_interop/all.html new file mode 100644 index 000000000..adf5cfb58 --- /dev/null +++ b/af_cuda_interop/all.html @@ -0,0 +1,19 @@ +List of all items in this crate + + + + + +

[] + + List of all items

Functions

\ No newline at end of file diff --git a/af_cuda_interop/fn.get_device_native_id.html b/af_cuda_interop/fn.get_device_native_id.html new file mode 100644 index 000000000..352753061 --- /dev/null +++ b/af_cuda_interop/fn.get_device_native_id.html @@ -0,0 +1,24 @@ +af_cuda_interop::get_device_native_id - Rust + + + + + +

[][src]Function af_cuda_interop::get_device_native_id

pub fn get_device_native_id(id: i32) -> i32

Get active device's id in CUDA context

+

Parameters

+
    +
  • id is the integer identifier of concerned CUDA device as per ArrayFire context
  • +
+

Return Values

+

Integer identifier of device in CUDA context

+
\ No newline at end of file diff --git a/af_cuda_interop/fn.get_stream.html b/af_cuda_interop/fn.get_stream.html new file mode 100644 index 000000000..381a40e9f --- /dev/null +++ b/af_cuda_interop/fn.get_stream.html @@ -0,0 +1,24 @@ +af_cuda_interop::get_stream - Rust + + + + + +

[][src]Function af_cuda_interop::get_stream

pub fn get_stream(native_id: i32) -> cudaStream_t

Get CUDA stream of active CUDA device

+

Parameters

+
    +
  • id is the identifier of device in ArrayFire context
  • +
+

Return Values

+

cudaStream_t handle.

+
\ No newline at end of file diff --git a/af_cuda_interop/fn.set_device_native_id.html b/af_cuda_interop/fn.set_device_native_id.html new file mode 100644 index 000000000..8ef313155 --- /dev/null +++ b/af_cuda_interop/fn.set_device_native_id.html @@ -0,0 +1,22 @@ +af_cuda_interop::set_device_native_id - Rust + + + + + +

[][src]Function af_cuda_interop::set_device_native_id

pub fn set_device_native_id(native_id: i32)

Set active device using CUDA context's id

+

Parameters

+
    +
  • id is the identifier of GPU in CUDA context
  • +
+
\ No newline at end of file diff --git a/af_cuda_interop/index.html b/af_cuda_interop/index.html new file mode 100644 index 000000000..fe7678d50 --- /dev/null +++ b/af_cuda_interop/index.html @@ -0,0 +1,23 @@ +af_cuda_interop - Rust + + + + + +

[][src]Crate af_cuda_interop

af-cuda-interop package is to used only when the application intends to mix +arrayfire code with raw CUDA code.

+

Functions

+
get_device_native_id

Get active device's id in CUDA context

+
get_stream

Get CUDA stream of active CUDA device

+
set_device_native_id

Set active device using CUDA context's id

+
\ No newline at end of file diff --git a/af_cuda_interop/sidebar-items.js b/af_cuda_interop/sidebar-items.js new file mode 100644 index 000000000..7a55d1a7b --- /dev/null +++ b/af_cuda_interop/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["get_device_native_id","Get active device's id in CUDA context"],["get_stream","Get CUDA stream of active CUDA device"],["set_device_native_id","Set active device using CUDA context's id"]]}); \ No newline at end of file diff --git a/af_opencl_interop/all.html b/af_opencl_interop/all.html new file mode 100644 index 000000000..c3bb898aa --- /dev/null +++ b/af_opencl_interop/all.html @@ -0,0 +1,19 @@ +List of all items in this crate + + + + + +

[] + + List of all items

Enums

Functions

\ No newline at end of file diff --git a/af_opencl_interop/enum.DeviceType.html b/af_opencl_interop/enum.DeviceType.html new file mode 100644 index 000000000..82bf7e68e --- /dev/null +++ b/af_opencl_interop/enum.DeviceType.html @@ -0,0 +1,45 @@ +af_opencl_interop::DeviceType - Rust + + + + + +

[][src]Enum af_opencl_interop::DeviceType

#[repr(u64)]pub enum DeviceType {
+    DEFAULT,
+    CPU,
+    GPU,
+    ACCEL,
+    ALL,
+}

OpenCL Device Type

+

+ Variants

+
DEFAULT
CPU
GPU
ACCEL
ALL

Trait Implementations

impl Clone for DeviceType[src]

impl Copy for DeviceType[src]

impl Debug for DeviceType[src]

impl PartialEq<DeviceType> for DeviceType[src]

impl StructuralPartialEq for DeviceType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/af_opencl_interop/enum.VendorPlatform.html b/af_opencl_interop/enum.VendorPlatform.html new file mode 100644 index 000000000..10a598046 --- /dev/null +++ b/af_opencl_interop/enum.VendorPlatform.html @@ -0,0 +1,47 @@ +af_opencl_interop::VendorPlatform - Rust + + + + + +

[][src]Enum af_opencl_interop::VendorPlatform

#[repr(i32)]pub enum VendorPlatform {
+    AMD,
+    APPLE,
+    INTEL,
+    NVIDIA,
+    BEIGNET,
+    POCL,
+    UNKNOWN,
+}

OpenCL Vendor Platform

+

+ Variants

+
AMD
APPLE
INTEL
NVIDIA
BEIGNET
POCL
UNKNOWN

Trait Implementations

impl Clone for VendorPlatform[src]

impl Copy for VendorPlatform[src]

impl Debug for VendorPlatform[src]

impl PartialEq<VendorPlatform> for VendorPlatform[src]

impl StructuralPartialEq for VendorPlatform[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.add_device_context.html b/af_opencl_interop/fn.add_device_context.html new file mode 100644 index 000000000..5a6ba7627 --- /dev/null +++ b/af_opencl_interop/fn.add_device_context.html @@ -0,0 +1,18 @@ +af_opencl_interop::add_device_context - Rust + + + + + +

[][src]Function af_opencl_interop::add_device_context

pub fn add_device_context(
    dev_id: cl_device_id,
    ctx: cl_context,
    queue: cl_command_queue
)

Push user provided device, context and queue tuple to ArrayFire device mamanger

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.delete_device_context.html b/af_opencl_interop/fn.delete_device_context.html new file mode 100644 index 000000000..42fbe3e0a --- /dev/null +++ b/af_opencl_interop/fn.delete_device_context.html @@ -0,0 +1,18 @@ +af_opencl_interop::delete_device_context - Rust + + + + + +

[][src]Function af_opencl_interop::delete_device_context

pub fn delete_device_context(dev_id: cl_device_id, ctx: cl_context)

Remove the user provided device, context pair from ArrayFire device mamanger

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.get_context.html b/af_opencl_interop/fn.get_context.html new file mode 100644 index 000000000..14bb27c0a --- /dev/null +++ b/af_opencl_interop/fn.get_context.html @@ -0,0 +1,18 @@ +af_opencl_interop::get_context - Rust + + + + + +

[][src]Function af_opencl_interop::get_context

pub fn get_context(retain: bool) -> cl_context

Get the handle to active ArrayFire OpenCL context

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.get_device_id.html b/af_opencl_interop/fn.get_device_id.html new file mode 100644 index 000000000..e2319a1e3 --- /dev/null +++ b/af_opencl_interop/fn.get_device_id.html @@ -0,0 +1,18 @@ +af_opencl_interop::get_device_id - Rust + + + + + +

[][src]Function af_opencl_interop::get_device_id

pub fn get_device_id() -> cl_device_id

Get the handle to active ArrayFire OpenCL device

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.get_device_type.html b/af_opencl_interop/fn.get_device_type.html new file mode 100644 index 000000000..351b132b3 --- /dev/null +++ b/af_opencl_interop/fn.get_device_type.html @@ -0,0 +1,17 @@ +af_opencl_interop::get_device_type - Rust + + + + + +

[][src]Function af_opencl_interop::get_device_type

pub fn get_device_type() -> DeviceType
\ No newline at end of file diff --git a/af_opencl_interop/fn.get_platform.html b/af_opencl_interop/fn.get_platform.html new file mode 100644 index 000000000..6730dbc33 --- /dev/null +++ b/af_opencl_interop/fn.get_platform.html @@ -0,0 +1,18 @@ +af_opencl_interop::get_platform - Rust + + + + + +

[][src]Function af_opencl_interop::get_platform

pub fn get_platform() -> VendorPlatform

Fetch Active ArrayFire device's vendor platform

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.get_queue.html b/af_opencl_interop/fn.get_queue.html new file mode 100644 index 000000000..09bfd518a --- /dev/null +++ b/af_opencl_interop/fn.get_queue.html @@ -0,0 +1,18 @@ +af_opencl_interop::get_queue - Rust + + + + + +

[][src]Function af_opencl_interop::get_queue

pub fn get_queue(retain: bool) -> cl_command_queue

Get the handle to active ArrayFire OpenCL command queue

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.set_device_context.html b/af_opencl_interop/fn.set_device_context.html new file mode 100644 index 000000000..57a1aa96a --- /dev/null +++ b/af_opencl_interop/fn.set_device_context.html @@ -0,0 +1,18 @@ +af_opencl_interop::set_device_context - Rust + + + + + +

[][src]Function af_opencl_interop::set_device_context

pub fn set_device_context(dev_id: cl_device_id, ctx: cl_context)

Set the device identified by device & context pair as the active device for ArrayFire

+
\ No newline at end of file diff --git a/af_opencl_interop/fn.set_device_id.html b/af_opencl_interop/fn.set_device_id.html new file mode 100644 index 000000000..542e5a9af --- /dev/null +++ b/af_opencl_interop/fn.set_device_id.html @@ -0,0 +1,18 @@ +af_opencl_interop::set_device_id - Rust + + + + + +

[][src]Function af_opencl_interop::set_device_id

pub fn set_device_id(dev_id: cl_device_id)

Set the cl_device_id as the active ArrayFire OpenCL device

+
\ No newline at end of file diff --git a/af_opencl_interop/index.html b/af_opencl_interop/index.html new file mode 100644 index 000000000..36b0befb4 --- /dev/null +++ b/af_opencl_interop/index.html @@ -0,0 +1,37 @@ +af_opencl_interop - Rust + + + + + +

[][src]Crate af_opencl_interop

af-opencl-interop package is to used only when the application intends to mix +arrayfire code with raw OpenCL code.

+

Functions from this crate return OpenCL C API opaque pointers typedefs

+ +

Enums

+
DeviceType

OpenCL Device Type

+
VendorPlatform

OpenCL Vendor Platform

+

Functions

+
add_device_context

Push user provided device, context and queue tuple to ArrayFire device mamanger

+
delete_device_context

Remove the user provided device, context pair from ArrayFire device mamanger

+
get_context

Get the handle to active ArrayFire OpenCL context

+
get_device_id

Get the handle to active ArrayFire OpenCL device

+
get_device_type
get_platform

Fetch Active ArrayFire device's vendor platform

+
get_queue

Get the handle to active ArrayFire OpenCL command queue

+
set_device_context

Set the device identified by device & context pair as the active device for ArrayFire

+
set_device_id

Set the cl_device_id as the active ArrayFire OpenCL device

+
\ No newline at end of file diff --git a/af_opencl_interop/sidebar-items.js b/af_opencl_interop/sidebar-items.js new file mode 100644 index 000000000..8f962b532 --- /dev/null +++ b/af_opencl_interop/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"enum":[["DeviceType","OpenCL Device Type"],["VendorPlatform","OpenCL Vendor Platform"]],"fn":[["add_device_context","Push user provided device, context and queue tuple to ArrayFire device mamanger"],["delete_device_context","Remove the user provided device, context pair from ArrayFire device mamanger"],["get_context","Get the handle to active ArrayFire OpenCL context"],["get_device_id","Get the handle to active ArrayFire OpenCL device"],["get_device_type",""],["get_platform","Fetch Active ArrayFire device's vendor platform"],["get_queue","Get the handle to active ArrayFire OpenCL command queue"],["set_device_context","Set the device identified by device & context pair as the active device for ArrayFire"],["set_device_id","Set the cl_device_id as the active ArrayFire OpenCL device"]]}); \ No newline at end of file diff --git a/arrayfire b/arrayfire deleted file mode 160000 index 218dd2c99..000000000 --- a/arrayfire +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 218dd2c99300e77496239ade76e94b0def65d032 diff --git a/arrayfire/algorithm/fn.accum.html b/arrayfire/algorithm/fn.accum.html new file mode 100644 index 000000000..84c7e66a0 --- /dev/null +++ b/arrayfire/algorithm/fn.accum.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.accum.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.all_true.html b/arrayfire/algorithm/fn.all_true.html new file mode 100644 index 000000000..f5448acbd --- /dev/null +++ b/arrayfire/algorithm/fn.all_true.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.all_true.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.all_true_all.html b/arrayfire/algorithm/fn.all_true_all.html new file mode 100644 index 000000000..cd6efef31 --- /dev/null +++ b/arrayfire/algorithm/fn.all_true_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.all_true_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.all_true_by_key.html b/arrayfire/algorithm/fn.all_true_by_key.html new file mode 100644 index 000000000..2bc991724 --- /dev/null +++ b/arrayfire/algorithm/fn.all_true_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.all_true_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.any_true.html b/arrayfire/algorithm/fn.any_true.html new file mode 100644 index 000000000..039802b91 --- /dev/null +++ b/arrayfire/algorithm/fn.any_true.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.any_true.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.any_true_all.html b/arrayfire/algorithm/fn.any_true_all.html new file mode 100644 index 000000000..d904953c7 --- /dev/null +++ b/arrayfire/algorithm/fn.any_true_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.any_true_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.any_true_by_key.html b/arrayfire/algorithm/fn.any_true_by_key.html new file mode 100644 index 000000000..1254e8e21 --- /dev/null +++ b/arrayfire/algorithm/fn.any_true_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.any_true_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.count.html b/arrayfire/algorithm/fn.count.html new file mode 100644 index 000000000..4bb0adcfe --- /dev/null +++ b/arrayfire/algorithm/fn.count.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.count.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.count_all.html b/arrayfire/algorithm/fn.count_all.html new file mode 100644 index 000000000..752bab27b --- /dev/null +++ b/arrayfire/algorithm/fn.count_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.count_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.count_by_key.html b/arrayfire/algorithm/fn.count_by_key.html new file mode 100644 index 000000000..8630cbcc0 --- /dev/null +++ b/arrayfire/algorithm/fn.count_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.count_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.diff1.html b/arrayfire/algorithm/fn.diff1.html new file mode 100644 index 000000000..f2cc635d1 --- /dev/null +++ b/arrayfire/algorithm/fn.diff1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.diff1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.diff2.html b/arrayfire/algorithm/fn.diff2.html new file mode 100644 index 000000000..9db2b4f83 --- /dev/null +++ b/arrayfire/algorithm/fn.diff2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.diff2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.imax.html b/arrayfire/algorithm/fn.imax.html new file mode 100644 index 000000000..9f4b89d11 --- /dev/null +++ b/arrayfire/algorithm/fn.imax.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.imax.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.imax_all.html b/arrayfire/algorithm/fn.imax_all.html new file mode 100644 index 000000000..868105e34 --- /dev/null +++ b/arrayfire/algorithm/fn.imax_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.imax_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.imin.html b/arrayfire/algorithm/fn.imin.html new file mode 100644 index 000000000..ec0c3746c --- /dev/null +++ b/arrayfire/algorithm/fn.imin.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.imin.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.imin_all.html b/arrayfire/algorithm/fn.imin_all.html new file mode 100644 index 000000000..6e61be84f --- /dev/null +++ b/arrayfire/algorithm/fn.imin_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.imin_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.locate.html b/arrayfire/algorithm/fn.locate.html new file mode 100644 index 000000000..03b852daa --- /dev/null +++ b/arrayfire/algorithm/fn.locate.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.locate.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.max.html b/arrayfire/algorithm/fn.max.html new file mode 100644 index 000000000..d4aebe3d4 --- /dev/null +++ b/arrayfire/algorithm/fn.max.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.max.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.max_all.html b/arrayfire/algorithm/fn.max_all.html new file mode 100644 index 000000000..7e61b4f83 --- /dev/null +++ b/arrayfire/algorithm/fn.max_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.max_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.max_by_key.html b/arrayfire/algorithm/fn.max_by_key.html new file mode 100644 index 000000000..f493bd510 --- /dev/null +++ b/arrayfire/algorithm/fn.max_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.max_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.max_ragged.html b/arrayfire/algorithm/fn.max_ragged.html new file mode 100644 index 000000000..3608e5996 --- /dev/null +++ b/arrayfire/algorithm/fn.max_ragged.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.max_ragged.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.min.html b/arrayfire/algorithm/fn.min.html new file mode 100644 index 000000000..0b8b9cbfc --- /dev/null +++ b/arrayfire/algorithm/fn.min.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.min.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.min_all.html b/arrayfire/algorithm/fn.min_all.html new file mode 100644 index 000000000..29dc63c24 --- /dev/null +++ b/arrayfire/algorithm/fn.min_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.min_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.min_by_key.html b/arrayfire/algorithm/fn.min_by_key.html new file mode 100644 index 000000000..c26d1b80e --- /dev/null +++ b/arrayfire/algorithm/fn.min_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.min_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product.html b/arrayfire/algorithm/fn.product.html new file mode 100644 index 000000000..de14fe572 --- /dev/null +++ b/arrayfire/algorithm/fn.product.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product_all.html b/arrayfire/algorithm/fn.product_all.html new file mode 100644 index 000000000..311cc2eef --- /dev/null +++ b/arrayfire/algorithm/fn.product_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product_by_key.html b/arrayfire/algorithm/fn.product_by_key.html new file mode 100644 index 000000000..6705547b7 --- /dev/null +++ b/arrayfire/algorithm/fn.product_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product_by_key_nan.html b/arrayfire/algorithm/fn.product_by_key_nan.html new file mode 100644 index 000000000..2e9ae2a82 --- /dev/null +++ b/arrayfire/algorithm/fn.product_by_key_nan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product_by_key_nan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product_nan.html b/arrayfire/algorithm/fn.product_nan.html new file mode 100644 index 000000000..92407bd34 --- /dev/null +++ b/arrayfire/algorithm/fn.product_nan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product_nan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.product_nan_all.html b/arrayfire/algorithm/fn.product_nan_all.html new file mode 100644 index 000000000..c9cf9f704 --- /dev/null +++ b/arrayfire/algorithm/fn.product_nan_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.product_nan_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.scan.html b/arrayfire/algorithm/fn.scan.html new file mode 100644 index 000000000..e511ea32e --- /dev/null +++ b/arrayfire/algorithm/fn.scan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.scan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.scan_by_key.html b/arrayfire/algorithm/fn.scan_by_key.html new file mode 100644 index 000000000..621391833 --- /dev/null +++ b/arrayfire/algorithm/fn.scan_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.scan_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.set_intersect.html b/arrayfire/algorithm/fn.set_intersect.html new file mode 100644 index 000000000..e6dd0c6f9 --- /dev/null +++ b/arrayfire/algorithm/fn.set_intersect.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.set_intersect.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.set_union.html b/arrayfire/algorithm/fn.set_union.html new file mode 100644 index 000000000..5b1ed0671 --- /dev/null +++ b/arrayfire/algorithm/fn.set_union.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.set_union.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.set_unique.html b/arrayfire/algorithm/fn.set_unique.html new file mode 100644 index 000000000..f42184893 --- /dev/null +++ b/arrayfire/algorithm/fn.set_unique.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.set_unique.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sort.html b/arrayfire/algorithm/fn.sort.html new file mode 100644 index 000000000..19bc66542 --- /dev/null +++ b/arrayfire/algorithm/fn.sort.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sort.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sort_by_key.html b/arrayfire/algorithm/fn.sort_by_key.html new file mode 100644 index 000000000..d4bf9d56a --- /dev/null +++ b/arrayfire/algorithm/fn.sort_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sort_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sort_index.html b/arrayfire/algorithm/fn.sort_index.html new file mode 100644 index 000000000..207b6308e --- /dev/null +++ b/arrayfire/algorithm/fn.sort_index.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sort_index.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum.html b/arrayfire/algorithm/fn.sum.html new file mode 100644 index 000000000..260e7e48a --- /dev/null +++ b/arrayfire/algorithm/fn.sum.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum_all.html b/arrayfire/algorithm/fn.sum_all.html new file mode 100644 index 000000000..26f749537 --- /dev/null +++ b/arrayfire/algorithm/fn.sum_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum_by_key.html b/arrayfire/algorithm/fn.sum_by_key.html new file mode 100644 index 000000000..6e9e14e7d --- /dev/null +++ b/arrayfire/algorithm/fn.sum_by_key.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum_by_key.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum_by_key_nan.html b/arrayfire/algorithm/fn.sum_by_key_nan.html new file mode 100644 index 000000000..fb2d4c19c --- /dev/null +++ b/arrayfire/algorithm/fn.sum_by_key_nan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum_by_key_nan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum_nan.html b/arrayfire/algorithm/fn.sum_nan.html new file mode 100644 index 000000000..01f750bb4 --- /dev/null +++ b/arrayfire/algorithm/fn.sum_nan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum_nan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/algorithm/fn.sum_nan_all.html b/arrayfire/algorithm/fn.sum_nan_all.html new file mode 100644 index 000000000..bfe65fba0 --- /dev/null +++ b/arrayfire/algorithm/fn.sum_nan_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sum_nan_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/all.html b/arrayfire/all.html new file mode 100644 index 000000000..e6e9bf165 --- /dev/null +++ b/arrayfire/all.html @@ -0,0 +1,17 @@ +List of all items in this crate + + + +

[] + + List of all items

Structs

Enums

Traits

Macros

Functions

Typedefs

Constants

\ No newline at end of file diff --git a/arrayfire/blas/fn.dot.html b/arrayfire/blas/fn.dot.html new file mode 100644 index 000000000..9b25f6692 --- /dev/null +++ b/arrayfire/blas/fn.dot.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.dot.html...

+ + + \ No newline at end of file diff --git a/arrayfire/blas/fn.gemm.html b/arrayfire/blas/fn.gemm.html new file mode 100644 index 000000000..9ada3e768 --- /dev/null +++ b/arrayfire/blas/fn.gemm.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.gemm.html...

+ + + \ No newline at end of file diff --git a/arrayfire/blas/fn.matmul.html b/arrayfire/blas/fn.matmul.html new file mode 100644 index 000000000..5e25b4c42 --- /dev/null +++ b/arrayfire/blas/fn.matmul.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.matmul.html...

+ + + \ No newline at end of file diff --git a/arrayfire/blas/fn.set_cublas_mode.html b/arrayfire/blas/fn.set_cublas_mode.html new file mode 100644 index 000000000..e70f7ba5c --- /dev/null +++ b/arrayfire/blas/fn.set_cublas_mode.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.set_cublas_mode.html...

+ + + \ No newline at end of file diff --git a/arrayfire/blas/fn.transpose.html b/arrayfire/blas/fn.transpose.html new file mode 100644 index 000000000..ea5d1f9e0 --- /dev/null +++ b/arrayfire/blas/fn.transpose.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.transpose.html...

+ + + \ No newline at end of file diff --git a/arrayfire/blas/fn.transpose_inplace.html b/arrayfire/blas/fn.transpose_inplace.html new file mode 100644 index 000000000..a2c0ee4c0 --- /dev/null +++ b/arrayfire/blas/fn.transpose_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.transpose_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/constant.DEFAULT_RANDOM_ENGINE.html b/arrayfire/constant.DEFAULT_RANDOM_ENGINE.html new file mode 100644 index 000000000..37e485ae5 --- /dev/null +++ b/arrayfire/constant.DEFAULT_RANDOM_ENGINE.html @@ -0,0 +1,16 @@ +arrayfire::DEFAULT_RANDOM_ENGINE - Rust + + + +

[][src]Constant arrayfire::DEFAULT_RANDOM_ENGINE

pub const DEFAULT_RANDOM_ENGINE: RandomEngineType;

Default RandomEngine that defaults to PHILOX

+
\ No newline at end of file diff --git a/arrayfire/constant.MERSENNE.html b/arrayfire/constant.MERSENNE.html new file mode 100644 index 000000000..08bfd4e04 --- /dev/null +++ b/arrayfire/constant.MERSENNE.html @@ -0,0 +1,16 @@ +arrayfire::MERSENNE - Rust + + + +

[][src]Constant arrayfire::MERSENNE

pub const MERSENNE: RandomEngineType;

Default Mersenne RandomEngine that points to MERSENNE_GP11213

+
\ No newline at end of file diff --git a/arrayfire/constant.PHILOX.html b/arrayfire/constant.PHILOX.html new file mode 100644 index 000000000..ebc7ea60d --- /dev/null +++ b/arrayfire/constant.PHILOX.html @@ -0,0 +1,16 @@ +arrayfire::PHILOX - Rust + + + +

[][src]Constant arrayfire::PHILOX

pub const PHILOX: RandomEngineType;

Default Philon RandomEngine that points to PHILOX_4X32_10

+
\ No newline at end of file diff --git a/arrayfire/constant.THREEFRY.html b/arrayfire/constant.THREEFRY.html new file mode 100644 index 000000000..dae35ce9c --- /dev/null +++ b/arrayfire/constant.THREEFRY.html @@ -0,0 +1,16 @@ +arrayfire::THREEFRY - Rust + + + +

[][src]Constant arrayfire::THREEFRY

pub const THREEFRY: RandomEngineType;

Default Threefry RandomEngine that points to THREEFRY_2X32_16

+
\ No newline at end of file diff --git a/arrayfire/core/arith/fn.abs.html b/arrayfire/core/arith/fn.abs.html new file mode 100644 index 000000000..747c6b901 --- /dev/null +++ b/arrayfire/core/arith/fn.abs.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.abs.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.acos.html b/arrayfire/core/arith/fn.acos.html new file mode 100644 index 000000000..2638e4952 --- /dev/null +++ b/arrayfire/core/arith/fn.acos.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.acos.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.acosh.html b/arrayfire/core/arith/fn.acosh.html new file mode 100644 index 000000000..7a7f930dc --- /dev/null +++ b/arrayfire/core/arith/fn.acosh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.acosh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.add.html b/arrayfire/core/arith/fn.add.html new file mode 100644 index 000000000..d3f5d53b6 --- /dev/null +++ b/arrayfire/core/arith/fn.add.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.add.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.and.html b/arrayfire/core/arith/fn.and.html new file mode 100644 index 000000000..6b816a595 --- /dev/null +++ b/arrayfire/core/arith/fn.and.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.and.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.arg.html b/arrayfire/core/arith/fn.arg.html new file mode 100644 index 000000000..3ced4fbe6 --- /dev/null +++ b/arrayfire/core/arith/fn.arg.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.arg.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.asin.html b/arrayfire/core/arith/fn.asin.html new file mode 100644 index 000000000..19ae4aa22 --- /dev/null +++ b/arrayfire/core/arith/fn.asin.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.asin.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.asinh.html b/arrayfire/core/arith/fn.asinh.html new file mode 100644 index 000000000..4a62a51d6 --- /dev/null +++ b/arrayfire/core/arith/fn.asinh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.asinh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.atan.html b/arrayfire/core/arith/fn.atan.html new file mode 100644 index 000000000..80f2fc9d9 --- /dev/null +++ b/arrayfire/core/arith/fn.atan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.atan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.atan2.html b/arrayfire/core/arith/fn.atan2.html new file mode 100644 index 000000000..e8e58ffc2 --- /dev/null +++ b/arrayfire/core/arith/fn.atan2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.atan2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.atanh.html b/arrayfire/core/arith/fn.atanh.html new file mode 100644 index 000000000..1a0d3afaf --- /dev/null +++ b/arrayfire/core/arith/fn.atanh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.atanh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.bitand.html b/arrayfire/core/arith/fn.bitand.html new file mode 100644 index 000000000..c30fa03d7 --- /dev/null +++ b/arrayfire/core/arith/fn.bitand.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.bitand.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.bitnot.html b/arrayfire/core/arith/fn.bitnot.html new file mode 100644 index 000000000..94205814d --- /dev/null +++ b/arrayfire/core/arith/fn.bitnot.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.bitnot.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.bitor.html b/arrayfire/core/arith/fn.bitor.html new file mode 100644 index 000000000..458f96b51 --- /dev/null +++ b/arrayfire/core/arith/fn.bitor.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.bitor.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.bitxor.html b/arrayfire/core/arith/fn.bitxor.html new file mode 100644 index 000000000..9de7af1f5 --- /dev/null +++ b/arrayfire/core/arith/fn.bitxor.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.bitxor.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.cbrt.html b/arrayfire/core/arith/fn.cbrt.html new file mode 100644 index 000000000..d3cb1003e --- /dev/null +++ b/arrayfire/core/arith/fn.cbrt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cbrt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.ceil.html b/arrayfire/core/arith/fn.ceil.html new file mode 100644 index 000000000..8d94f47d9 --- /dev/null +++ b/arrayfire/core/arith/fn.ceil.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.ceil.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.clamp.html b/arrayfire/core/arith/fn.clamp.html new file mode 100644 index 000000000..5652077ce --- /dev/null +++ b/arrayfire/core/arith/fn.clamp.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.clamp.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.conjg.html b/arrayfire/core/arith/fn.conjg.html new file mode 100644 index 000000000..740c9ea9b --- /dev/null +++ b/arrayfire/core/arith/fn.conjg.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.conjg.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.cos.html b/arrayfire/core/arith/fn.cos.html new file mode 100644 index 000000000..89e96030b --- /dev/null +++ b/arrayfire/core/arith/fn.cos.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cos.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.cosh.html b/arrayfire/core/arith/fn.cosh.html new file mode 100644 index 000000000..1aab23230 --- /dev/null +++ b/arrayfire/core/arith/fn.cosh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cosh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.cplx.html b/arrayfire/core/arith/fn.cplx.html new file mode 100644 index 000000000..936fb5193 --- /dev/null +++ b/arrayfire/core/arith/fn.cplx.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cplx.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.cplx2.html b/arrayfire/core/arith/fn.cplx2.html new file mode 100644 index 000000000..5e75a6549 --- /dev/null +++ b/arrayfire/core/arith/fn.cplx2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cplx2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.div.html b/arrayfire/core/arith/fn.div.html new file mode 100644 index 000000000..1b8d6be23 --- /dev/null +++ b/arrayfire/core/arith/fn.div.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.div.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.eq.html b/arrayfire/core/arith/fn.eq.html new file mode 100644 index 000000000..011bfdddc --- /dev/null +++ b/arrayfire/core/arith/fn.eq.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.eq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.erf.html b/arrayfire/core/arith/fn.erf.html new file mode 100644 index 000000000..7fb593553 --- /dev/null +++ b/arrayfire/core/arith/fn.erf.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.erf.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.erfc.html b/arrayfire/core/arith/fn.erfc.html new file mode 100644 index 000000000..6eaebf8e6 --- /dev/null +++ b/arrayfire/core/arith/fn.erfc.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.erfc.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.exp.html b/arrayfire/core/arith/fn.exp.html new file mode 100644 index 000000000..76f62136d --- /dev/null +++ b/arrayfire/core/arith/fn.exp.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.exp.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.expm1.html b/arrayfire/core/arith/fn.expm1.html new file mode 100644 index 000000000..4da265800 --- /dev/null +++ b/arrayfire/core/arith/fn.expm1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.expm1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.factorial.html b/arrayfire/core/arith/fn.factorial.html new file mode 100644 index 000000000..036ded508 --- /dev/null +++ b/arrayfire/core/arith/fn.factorial.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.factorial.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.floor.html b/arrayfire/core/arith/fn.floor.html new file mode 100644 index 000000000..3e0ad025a --- /dev/null +++ b/arrayfire/core/arith/fn.floor.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.floor.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.ge.html b/arrayfire/core/arith/fn.ge.html new file mode 100644 index 000000000..370ac683e --- /dev/null +++ b/arrayfire/core/arith/fn.ge.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.ge.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.gt.html b/arrayfire/core/arith/fn.gt.html new file mode 100644 index 000000000..0ad917667 --- /dev/null +++ b/arrayfire/core/arith/fn.gt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.gt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.hypot.html b/arrayfire/core/arith/fn.hypot.html new file mode 100644 index 000000000..5048e52a7 --- /dev/null +++ b/arrayfire/core/arith/fn.hypot.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.hypot.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.imag.html b/arrayfire/core/arith/fn.imag.html new file mode 100644 index 000000000..878edbf91 --- /dev/null +++ b/arrayfire/core/arith/fn.imag.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.imag.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.isinf.html b/arrayfire/core/arith/fn.isinf.html new file mode 100644 index 000000000..db01d9405 --- /dev/null +++ b/arrayfire/core/arith/fn.isinf.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.isinf.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.isnan.html b/arrayfire/core/arith/fn.isnan.html new file mode 100644 index 000000000..3b4c55186 --- /dev/null +++ b/arrayfire/core/arith/fn.isnan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.isnan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.iszero.html b/arrayfire/core/arith/fn.iszero.html new file mode 100644 index 000000000..2bb7d2ff9 --- /dev/null +++ b/arrayfire/core/arith/fn.iszero.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.iszero.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.le.html b/arrayfire/core/arith/fn.le.html new file mode 100644 index 000000000..6c4012a29 --- /dev/null +++ b/arrayfire/core/arith/fn.le.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.le.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.lgamma.html b/arrayfire/core/arith/fn.lgamma.html new file mode 100644 index 000000000..aa15934a6 --- /dev/null +++ b/arrayfire/core/arith/fn.lgamma.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.lgamma.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.log.html b/arrayfire/core/arith/fn.log.html new file mode 100644 index 000000000..ee8350d53 --- /dev/null +++ b/arrayfire/core/arith/fn.log.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.log.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.log10.html b/arrayfire/core/arith/fn.log10.html new file mode 100644 index 000000000..3b947472b --- /dev/null +++ b/arrayfire/core/arith/fn.log10.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.log10.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.log1p.html b/arrayfire/core/arith/fn.log1p.html new file mode 100644 index 000000000..2bc3ea38c --- /dev/null +++ b/arrayfire/core/arith/fn.log1p.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.log1p.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.log2.html b/arrayfire/core/arith/fn.log2.html new file mode 100644 index 000000000..6af9e4562 --- /dev/null +++ b/arrayfire/core/arith/fn.log2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.log2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.lt.html b/arrayfire/core/arith/fn.lt.html new file mode 100644 index 000000000..9aae45dfd --- /dev/null +++ b/arrayfire/core/arith/fn.lt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.lt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.maxof.html b/arrayfire/core/arith/fn.maxof.html new file mode 100644 index 000000000..eac92109e --- /dev/null +++ b/arrayfire/core/arith/fn.maxof.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.maxof.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.minof.html b/arrayfire/core/arith/fn.minof.html new file mode 100644 index 000000000..82dc2717c --- /dev/null +++ b/arrayfire/core/arith/fn.minof.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.minof.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.modulo.html b/arrayfire/core/arith/fn.modulo.html new file mode 100644 index 000000000..b3d3f44c6 --- /dev/null +++ b/arrayfire/core/arith/fn.modulo.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.modulo.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.mul.html b/arrayfire/core/arith/fn.mul.html new file mode 100644 index 000000000..32c2a035f --- /dev/null +++ b/arrayfire/core/arith/fn.mul.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.mul.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.neq.html b/arrayfire/core/arith/fn.neq.html new file mode 100644 index 000000000..92000cece --- /dev/null +++ b/arrayfire/core/arith/fn.neq.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.neq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.or.html b/arrayfire/core/arith/fn.or.html new file mode 100644 index 000000000..10697cda9 --- /dev/null +++ b/arrayfire/core/arith/fn.or.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.or.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.pow.html b/arrayfire/core/arith/fn.pow.html new file mode 100644 index 000000000..12b69fbb8 --- /dev/null +++ b/arrayfire/core/arith/fn.pow.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.pow.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.pow2.html b/arrayfire/core/arith/fn.pow2.html new file mode 100644 index 000000000..23148f795 --- /dev/null +++ b/arrayfire/core/arith/fn.pow2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.pow2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.real.html b/arrayfire/core/arith/fn.real.html new file mode 100644 index 000000000..559168785 --- /dev/null +++ b/arrayfire/core/arith/fn.real.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.real.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.rem.html b/arrayfire/core/arith/fn.rem.html new file mode 100644 index 000000000..48f53c50b --- /dev/null +++ b/arrayfire/core/arith/fn.rem.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.rem.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.root.html b/arrayfire/core/arith/fn.root.html new file mode 100644 index 000000000..6f4d5e2d5 --- /dev/null +++ b/arrayfire/core/arith/fn.root.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.root.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.round.html b/arrayfire/core/arith/fn.round.html new file mode 100644 index 000000000..09d668c27 --- /dev/null +++ b/arrayfire/core/arith/fn.round.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.round.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.rsqrt.html b/arrayfire/core/arith/fn.rsqrt.html new file mode 100644 index 000000000..520eb7d9b --- /dev/null +++ b/arrayfire/core/arith/fn.rsqrt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.rsqrt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.shiftl.html b/arrayfire/core/arith/fn.shiftl.html new file mode 100644 index 000000000..7e78b84d3 --- /dev/null +++ b/arrayfire/core/arith/fn.shiftl.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.shiftl.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.shiftr.html b/arrayfire/core/arith/fn.shiftr.html new file mode 100644 index 000000000..f2288f207 --- /dev/null +++ b/arrayfire/core/arith/fn.shiftr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.shiftr.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sigmoid.html b/arrayfire/core/arith/fn.sigmoid.html new file mode 100644 index 000000000..003270752 --- /dev/null +++ b/arrayfire/core/arith/fn.sigmoid.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sigmoid.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sign.html b/arrayfire/core/arith/fn.sign.html new file mode 100644 index 000000000..a17193e22 --- /dev/null +++ b/arrayfire/core/arith/fn.sign.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sign.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sin.html b/arrayfire/core/arith/fn.sin.html new file mode 100644 index 000000000..02bb60323 --- /dev/null +++ b/arrayfire/core/arith/fn.sin.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sin.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sinh.html b/arrayfire/core/arith/fn.sinh.html new file mode 100644 index 000000000..7450740f4 --- /dev/null +++ b/arrayfire/core/arith/fn.sinh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sinh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sqrt.html b/arrayfire/core/arith/fn.sqrt.html new file mode 100644 index 000000000..5e4e3d9c2 --- /dev/null +++ b/arrayfire/core/arith/fn.sqrt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sqrt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.sub.html b/arrayfire/core/arith/fn.sub.html new file mode 100644 index 000000000..d47a08b98 --- /dev/null +++ b/arrayfire/core/arith/fn.sub.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sub.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.tan.html b/arrayfire/core/arith/fn.tan.html new file mode 100644 index 000000000..9a9d0e4c5 --- /dev/null +++ b/arrayfire/core/arith/fn.tan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.tan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.tanh.html b/arrayfire/core/arith/fn.tanh.html new file mode 100644 index 000000000..afbd8970a --- /dev/null +++ b/arrayfire/core/arith/fn.tanh.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.tanh.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.tgamma.html b/arrayfire/core/arith/fn.tgamma.html new file mode 100644 index 000000000..fa86f95ba --- /dev/null +++ b/arrayfire/core/arith/fn.tgamma.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.tgamma.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/fn.trunc.html b/arrayfire/core/arith/fn.trunc.html new file mode 100644 index 000000000..799167c56 --- /dev/null +++ b/arrayfire/core/arith/fn.trunc.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.trunc.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/arith/trait.Convertable.html b/arrayfire/core/arith/trait.Convertable.html new file mode 100644 index 000000000..510116bf8 --- /dev/null +++ b/arrayfire/core/arith/trait.Convertable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.Convertable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/fn.eval_multiple.html b/arrayfire/core/array/fn.eval_multiple.html new file mode 100644 index 000000000..ec160ccc0 --- /dev/null +++ b/arrayfire/core/array/fn.eval_multiple.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.eval_multiple.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/fn.is_eval_manual.html b/arrayfire/core/array/fn.is_eval_manual.html new file mode 100644 index 000000000..56aed5593 --- /dev/null +++ b/arrayfire/core/array/fn.is_eval_manual.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.is_eval_manual.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/fn.print.html b/arrayfire/core/array/fn.print.html new file mode 100644 index 000000000..d68787f62 --- /dev/null +++ b/arrayfire/core/array/fn.print.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.print.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/fn.print_gen.html b/arrayfire/core/array/fn.print_gen.html new file mode 100644 index 000000000..5633525cb --- /dev/null +++ b/arrayfire/core/array/fn.print_gen.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.print_gen.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/fn.set_manual_eval.html b/arrayfire/core/array/fn.set_manual_eval.html new file mode 100644 index 000000000..bc5bbfe48 --- /dev/null +++ b/arrayfire/core/array/fn.set_manual_eval.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_manual_eval.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/array/struct.Array.html b/arrayfire/core/array/struct.Array.html new file mode 100644 index 000000000..1f09ca19f --- /dev/null +++ b/arrayfire/core/array/struct.Array.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Array.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/backend/fn.get_active_backend.html b/arrayfire/core/backend/fn.get_active_backend.html new file mode 100644 index 000000000..6e7b302c2 --- /dev/null +++ b/arrayfire/core/backend/fn.get_active_backend.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_active_backend.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/backend/fn.get_available_backends.html b/arrayfire/core/backend/fn.get_available_backends.html new file mode 100644 index 000000000..3d8b997d1 --- /dev/null +++ b/arrayfire/core/backend/fn.get_available_backends.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_available_backends.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/backend/fn.get_backend_count.html b/arrayfire/core/backend/fn.get_backend_count.html new file mode 100644 index 000000000..1060dd719 --- /dev/null +++ b/arrayfire/core/backend/fn.get_backend_count.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_backend_count.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/backend/fn.set_backend.html b/arrayfire/core/backend/fn.set_backend.html new file mode 100644 index 000000000..b4091f975 --- /dev/null +++ b/arrayfire/core/backend/fn.set_backend.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_backend.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.constant.html b/arrayfire/core/data/fn.constant.html new file mode 100644 index 000000000..c318b1507 --- /dev/null +++ b/arrayfire/core/data/fn.constant.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.constant.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.diag_create.html b/arrayfire/core/data/fn.diag_create.html new file mode 100644 index 000000000..b8fe1d8a4 --- /dev/null +++ b/arrayfire/core/data/fn.diag_create.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.diag_create.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.diag_extract.html b/arrayfire/core/data/fn.diag_extract.html new file mode 100644 index 000000000..81a22f227 --- /dev/null +++ b/arrayfire/core/data/fn.diag_extract.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.diag_extract.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.flat.html b/arrayfire/core/data/fn.flat.html new file mode 100644 index 000000000..9ebe5348a --- /dev/null +++ b/arrayfire/core/data/fn.flat.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.flat.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.flip.html b/arrayfire/core/data/fn.flip.html new file mode 100644 index 000000000..f086b4bca --- /dev/null +++ b/arrayfire/core/data/fn.flip.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.flip.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.identity.html b/arrayfire/core/data/fn.identity.html new file mode 100644 index 000000000..92f11d109 --- /dev/null +++ b/arrayfire/core/data/fn.identity.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.identity.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.iota.html b/arrayfire/core/data/fn.iota.html new file mode 100644 index 000000000..a04f35f09 --- /dev/null +++ b/arrayfire/core/data/fn.iota.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.iota.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.join.html b/arrayfire/core/data/fn.join.html new file mode 100644 index 000000000..9c197ef8d --- /dev/null +++ b/arrayfire/core/data/fn.join.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.join.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.join_many.html b/arrayfire/core/data/fn.join_many.html new file mode 100644 index 000000000..e302cd939 --- /dev/null +++ b/arrayfire/core/data/fn.join_many.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.join_many.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.lower.html b/arrayfire/core/data/fn.lower.html new file mode 100644 index 000000000..00254565e --- /dev/null +++ b/arrayfire/core/data/fn.lower.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.lower.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.moddims.html b/arrayfire/core/data/fn.moddims.html new file mode 100644 index 000000000..41cdc958c --- /dev/null +++ b/arrayfire/core/data/fn.moddims.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.moddims.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.pad.html b/arrayfire/core/data/fn.pad.html new file mode 100644 index 000000000..a77aee410 --- /dev/null +++ b/arrayfire/core/data/fn.pad.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.pad.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.range.html b/arrayfire/core/data/fn.range.html new file mode 100644 index 000000000..47c646ad9 --- /dev/null +++ b/arrayfire/core/data/fn.range.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.range.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.reorder.html b/arrayfire/core/data/fn.reorder.html new file mode 100644 index 000000000..34ee7ac17 --- /dev/null +++ b/arrayfire/core/data/fn.reorder.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.reorder.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.reorder_v2.html b/arrayfire/core/data/fn.reorder_v2.html new file mode 100644 index 000000000..b9893fc9b --- /dev/null +++ b/arrayfire/core/data/fn.reorder_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.reorder_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.replace.html b/arrayfire/core/data/fn.replace.html new file mode 100644 index 000000000..916b469f7 --- /dev/null +++ b/arrayfire/core/data/fn.replace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.replace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.replace_scalar.html b/arrayfire/core/data/fn.replace_scalar.html new file mode 100644 index 000000000..035cd3d9d --- /dev/null +++ b/arrayfire/core/data/fn.replace_scalar.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.replace_scalar.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.select.html b/arrayfire/core/data/fn.select.html new file mode 100644 index 000000000..4f8140ae9 --- /dev/null +++ b/arrayfire/core/data/fn.select.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.select.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.selectl.html b/arrayfire/core/data/fn.selectl.html new file mode 100644 index 000000000..a5d14ae7e --- /dev/null +++ b/arrayfire/core/data/fn.selectl.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.selectl.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.selectr.html b/arrayfire/core/data/fn.selectr.html new file mode 100644 index 000000000..2af2c42e6 --- /dev/null +++ b/arrayfire/core/data/fn.selectr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.selectr.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.shift.html b/arrayfire/core/data/fn.shift.html new file mode 100644 index 000000000..7aa7e1a28 --- /dev/null +++ b/arrayfire/core/data/fn.shift.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.shift.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.tile.html b/arrayfire/core/data/fn.tile.html new file mode 100644 index 000000000..f66f33eeb --- /dev/null +++ b/arrayfire/core/data/fn.tile.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.tile.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/fn.upper.html b/arrayfire/core/data/fn.upper.html new file mode 100644 index 000000000..b05c55b20 --- /dev/null +++ b/arrayfire/core/data/fn.upper.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.upper.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/data/trait.ConstGenerator.html b/arrayfire/core/data/trait.ConstGenerator.html new file mode 100644 index 000000000..b1e650669 --- /dev/null +++ b/arrayfire/core/data/trait.ConstGenerator.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ConstGenerator.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/constant.DEFAULT_RANDOM_ENGINE.html b/arrayfire/core/defines/constant.DEFAULT_RANDOM_ENGINE.html new file mode 100644 index 000000000..0e65f760f --- /dev/null +++ b/arrayfire/core/defines/constant.DEFAULT_RANDOM_ENGINE.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/constant.DEFAULT_RANDOM_ENGINE.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/constant.MERSENNE.html b/arrayfire/core/defines/constant.MERSENNE.html new file mode 100644 index 000000000..6e377bb9e --- /dev/null +++ b/arrayfire/core/defines/constant.MERSENNE.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/constant.MERSENNE.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/constant.PHILOX.html b/arrayfire/core/defines/constant.PHILOX.html new file mode 100644 index 000000000..dde01222d --- /dev/null +++ b/arrayfire/core/defines/constant.PHILOX.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/constant.PHILOX.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/constant.THREEFRY.html b/arrayfire/core/defines/constant.THREEFRY.html new file mode 100644 index 000000000..a4f34b292 --- /dev/null +++ b/arrayfire/core/defines/constant.THREEFRY.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/constant.THREEFRY.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.AfError.html b/arrayfire/core/defines/enum.AfError.html new file mode 100644 index 000000000..16c09ce01 --- /dev/null +++ b/arrayfire/core/defines/enum.AfError.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.AfError.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.Backend.html b/arrayfire/core/defines/enum.Backend.html new file mode 100644 index 000000000..4997a8cb4 --- /dev/null +++ b/arrayfire/core/defines/enum.Backend.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.Backend.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.BinaryOp.html b/arrayfire/core/defines/enum.BinaryOp.html new file mode 100644 index 000000000..37fa659d5 --- /dev/null +++ b/arrayfire/core/defines/enum.BinaryOp.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.BinaryOp.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.BorderType.html b/arrayfire/core/defines/enum.BorderType.html new file mode 100644 index 000000000..6f297cafa --- /dev/null +++ b/arrayfire/core/defines/enum.BorderType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.BorderType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.CannyThresholdType.html b/arrayfire/core/defines/enum.CannyThresholdType.html new file mode 100644 index 000000000..8ee6750d0 --- /dev/null +++ b/arrayfire/core/defines/enum.CannyThresholdType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.CannyThresholdType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.ColorMap.html b/arrayfire/core/defines/enum.ColorMap.html new file mode 100644 index 000000000..74e09d194 --- /dev/null +++ b/arrayfire/core/defines/enum.ColorMap.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.ColorMap.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.ColorSpace.html b/arrayfire/core/defines/enum.ColorSpace.html new file mode 100644 index 000000000..7d159ed0d --- /dev/null +++ b/arrayfire/core/defines/enum.ColorSpace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.ColorSpace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.Connectivity.html b/arrayfire/core/defines/enum.Connectivity.html new file mode 100644 index 000000000..33780a42d --- /dev/null +++ b/arrayfire/core/defines/enum.Connectivity.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.Connectivity.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.ConvDomain.html b/arrayfire/core/defines/enum.ConvDomain.html new file mode 100644 index 000000000..769c2029b --- /dev/null +++ b/arrayfire/core/defines/enum.ConvDomain.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.ConvDomain.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.ConvGradientType.html b/arrayfire/core/defines/enum.ConvGradientType.html new file mode 100644 index 000000000..c25bfec10 --- /dev/null +++ b/arrayfire/core/defines/enum.ConvGradientType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.ConvGradientType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.ConvMode.html b/arrayfire/core/defines/enum.ConvMode.html new file mode 100644 index 000000000..b332907f7 --- /dev/null +++ b/arrayfire/core/defines/enum.ConvMode.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.ConvMode.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.CublasMathMode.html b/arrayfire/core/defines/enum.CublasMathMode.html new file mode 100644 index 000000000..11e703e28 --- /dev/null +++ b/arrayfire/core/defines/enum.CublasMathMode.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.CublasMathMode.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.DType.html b/arrayfire/core/defines/enum.DType.html new file mode 100644 index 000000000..d07d48f8f --- /dev/null +++ b/arrayfire/core/defines/enum.DType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.DType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.DiffusionEq.html b/arrayfire/core/defines/enum.DiffusionEq.html new file mode 100644 index 000000000..ee7e176f0 --- /dev/null +++ b/arrayfire/core/defines/enum.DiffusionEq.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.DiffusionEq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.FluxFn.html b/arrayfire/core/defines/enum.FluxFn.html new file mode 100644 index 000000000..2059466f7 --- /dev/null +++ b/arrayfire/core/defines/enum.FluxFn.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.FluxFn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.HomographyType.html b/arrayfire/core/defines/enum.HomographyType.html new file mode 100644 index 000000000..4cb03449b --- /dev/null +++ b/arrayfire/core/defines/enum.HomographyType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.HomographyType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.InterpType.html b/arrayfire/core/defines/enum.InterpType.html new file mode 100644 index 000000000..42a92a27c --- /dev/null +++ b/arrayfire/core/defines/enum.InterpType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.InterpType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.InverseDeconvAlgo.html b/arrayfire/core/defines/enum.InverseDeconvAlgo.html new file mode 100644 index 000000000..a283875ee --- /dev/null +++ b/arrayfire/core/defines/enum.InverseDeconvAlgo.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.InverseDeconvAlgo.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.IterativeDeconvAlgo.html b/arrayfire/core/defines/enum.IterativeDeconvAlgo.html new file mode 100644 index 000000000..71399f09b --- /dev/null +++ b/arrayfire/core/defines/enum.IterativeDeconvAlgo.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.IterativeDeconvAlgo.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.MarkerType.html b/arrayfire/core/defines/enum.MarkerType.html new file mode 100644 index 000000000..3e3448361 --- /dev/null +++ b/arrayfire/core/defines/enum.MarkerType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.MarkerType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.MatProp.html b/arrayfire/core/defines/enum.MatProp.html new file mode 100644 index 000000000..291ebca71 --- /dev/null +++ b/arrayfire/core/defines/enum.MatProp.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.MatProp.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.MatchType.html b/arrayfire/core/defines/enum.MatchType.html new file mode 100644 index 000000000..1261acd17 --- /dev/null +++ b/arrayfire/core/defines/enum.MatchType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.MatchType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.MomentType.html b/arrayfire/core/defines/enum.MomentType.html new file mode 100644 index 000000000..81fb9f209 --- /dev/null +++ b/arrayfire/core/defines/enum.MomentType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.MomentType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.NormType.html b/arrayfire/core/defines/enum.NormType.html new file mode 100644 index 000000000..f86067371 --- /dev/null +++ b/arrayfire/core/defines/enum.NormType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.NormType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.RandomEngineType.html b/arrayfire/core/defines/enum.RandomEngineType.html new file mode 100644 index 000000000..2634de60e --- /dev/null +++ b/arrayfire/core/defines/enum.RandomEngineType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.RandomEngineType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.Scalar.html b/arrayfire/core/defines/enum.Scalar.html new file mode 100644 index 000000000..ba5d90793 --- /dev/null +++ b/arrayfire/core/defines/enum.Scalar.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.Scalar.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.SparseFormat.html b/arrayfire/core/defines/enum.SparseFormat.html new file mode 100644 index 000000000..05ae6799a --- /dev/null +++ b/arrayfire/core/defines/enum.SparseFormat.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.SparseFormat.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.TopkFn.html b/arrayfire/core/defines/enum.TopkFn.html new file mode 100644 index 000000000..9b560dd2a --- /dev/null +++ b/arrayfire/core/defines/enum.TopkFn.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.TopkFn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.VarianceBias.html b/arrayfire/core/defines/enum.VarianceBias.html new file mode 100644 index 000000000..2b16d98c6 --- /dev/null +++ b/arrayfire/core/defines/enum.VarianceBias.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.VarianceBias.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/defines/enum.YCCStd.html b/arrayfire/core/defines/enum.YCCStd.html new file mode 100644 index 000000000..c317f181d --- /dev/null +++ b/arrayfire/core/defines/enum.YCCStd.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/enum.YCCStd.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.alloc_pinned.html b/arrayfire/core/device/fn.alloc_pinned.html new file mode 100644 index 000000000..a0dd1a4dd --- /dev/null +++ b/arrayfire/core/device/fn.alloc_pinned.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.alloc_pinned.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.device_count.html b/arrayfire/core/device/fn.device_count.html new file mode 100644 index 000000000..2c4484304 --- /dev/null +++ b/arrayfire/core/device/fn.device_count.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.device_count.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.device_gc.html b/arrayfire/core/device/fn.device_gc.html new file mode 100644 index 000000000..920c56d50 --- /dev/null +++ b/arrayfire/core/device/fn.device_gc.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.device_gc.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.device_info.html b/arrayfire/core/device/fn.device_info.html new file mode 100644 index 000000000..a21ddf364 --- /dev/null +++ b/arrayfire/core/device/fn.device_info.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.device_info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.device_mem_info.html b/arrayfire/core/device/fn.device_mem_info.html new file mode 100644 index 000000000..f27717fdc --- /dev/null +++ b/arrayfire/core/device/fn.device_mem_info.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.device_mem_info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.free_pinned.html b/arrayfire/core/device/fn.free_pinned.html new file mode 100644 index 000000000..082f235c4 --- /dev/null +++ b/arrayfire/core/device/fn.free_pinned.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.free_pinned.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.get_device.html b/arrayfire/core/device/fn.get_device.html new file mode 100644 index 000000000..bfecca213 --- /dev/null +++ b/arrayfire/core/device/fn.get_device.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_device.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.get_mem_step_size.html b/arrayfire/core/device/fn.get_mem_step_size.html new file mode 100644 index 000000000..296e12bc9 --- /dev/null +++ b/arrayfire/core/device/fn.get_mem_step_size.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_mem_step_size.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.get_revision.html b/arrayfire/core/device/fn.get_revision.html new file mode 100644 index 000000000..abd736ebc --- /dev/null +++ b/arrayfire/core/device/fn.get_revision.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_revision.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.get_version.html b/arrayfire/core/device/fn.get_version.html new file mode 100644 index 000000000..b1dd02bc9 --- /dev/null +++ b/arrayfire/core/device/fn.get_version.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_version.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.info.html b/arrayfire/core/device/fn.info.html new file mode 100644 index 000000000..b05903bd9 --- /dev/null +++ b/arrayfire/core/device/fn.info.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.info_string.html b/arrayfire/core/device/fn.info_string.html new file mode 100644 index 000000000..369ca4c2f --- /dev/null +++ b/arrayfire/core/device/fn.info_string.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.info_string.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.init.html b/arrayfire/core/device/fn.init.html new file mode 100644 index 000000000..153f20db3 --- /dev/null +++ b/arrayfire/core/device/fn.init.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.init.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.is_double_available.html b/arrayfire/core/device/fn.is_double_available.html new file mode 100644 index 000000000..a312e23da --- /dev/null +++ b/arrayfire/core/device/fn.is_double_available.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.is_double_available.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.is_half_available.html b/arrayfire/core/device/fn.is_half_available.html new file mode 100644 index 000000000..36e384b00 --- /dev/null +++ b/arrayfire/core/device/fn.is_half_available.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.is_half_available.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.print_mem_info.html b/arrayfire/core/device/fn.print_mem_info.html new file mode 100644 index 000000000..aba6252d7 --- /dev/null +++ b/arrayfire/core/device/fn.print_mem_info.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.print_mem_info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.set_device.html b/arrayfire/core/device/fn.set_device.html new file mode 100644 index 000000000..e9b9021a7 --- /dev/null +++ b/arrayfire/core/device/fn.set_device.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_device.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.set_mem_step_size.html b/arrayfire/core/device/fn.set_mem_step_size.html new file mode 100644 index 000000000..d28077b21 --- /dev/null +++ b/arrayfire/core/device/fn.set_mem_step_size.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_mem_step_size.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/device/fn.sync.html b/arrayfire/core/device/fn.sync.html new file mode 100644 index 000000000..f17cec391 --- /dev/null +++ b/arrayfire/core/device/fn.sync.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.sync.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/dim4/struct.Dim4.html b/arrayfire/core/dim4/struct.Dim4.html new file mode 100644 index 000000000..aa716a7fa --- /dev/null +++ b/arrayfire/core/dim4/struct.Dim4.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Dim4.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/fn.HANDLE_ERROR.html b/arrayfire/core/error/fn.HANDLE_ERROR.html new file mode 100644 index 000000000..fbad3685e --- /dev/null +++ b/arrayfire/core/error/fn.HANDLE_ERROR.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.HANDLE_ERROR.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/fn.get_last_error.html b/arrayfire/core/error/fn.get_last_error.html new file mode 100644 index 000000000..b52582da4 --- /dev/null +++ b/arrayfire/core/error/fn.get_last_error.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_last_error.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/fn.handle_error_general.html b/arrayfire/core/error/fn.handle_error_general.html new file mode 100644 index 000000000..0080bdd87 --- /dev/null +++ b/arrayfire/core/error/fn.handle_error_general.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.handle_error_general.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/fn.register_error_handler.html b/arrayfire/core/error/fn.register_error_handler.html new file mode 100644 index 000000000..b2214450c --- /dev/null +++ b/arrayfire/core/error/fn.register_error_handler.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.register_error_handler.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/struct.Callback.html b/arrayfire/core/error/struct.Callback.html new file mode 100644 index 000000000..5244cd99d --- /dev/null +++ b/arrayfire/core/error/struct.Callback.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Callback.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/error/type.ErrorCallback.html b/arrayfire/core/error/type.ErrorCallback.html new file mode 100644 index 000000000..fcd630e42 --- /dev/null +++ b/arrayfire/core/error/type.ErrorCallback.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.ErrorCallback.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/event/struct.Event.html b/arrayfire/core/event/struct.Event.html new file mode 100644 index 000000000..e85f9e027 --- /dev/null +++ b/arrayfire/core/event/struct.Event.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Event.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.assign_gen.html b/arrayfire/core/index/fn.assign_gen.html new file mode 100644 index 000000000..567f5c33b --- /dev/null +++ b/arrayfire/core/index/fn.assign_gen.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.assign_gen.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.assign_seq.html b/arrayfire/core/index/fn.assign_seq.html new file mode 100644 index 000000000..63d983d22 --- /dev/null +++ b/arrayfire/core/index/fn.assign_seq.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.assign_seq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.col.html b/arrayfire/core/index/fn.col.html new file mode 100644 index 000000000..82cb7b072 --- /dev/null +++ b/arrayfire/core/index/fn.col.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.col.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.cols.html b/arrayfire/core/index/fn.cols.html new file mode 100644 index 000000000..cb45743c5 --- /dev/null +++ b/arrayfire/core/index/fn.cols.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.cols.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.index.html b/arrayfire/core/index/fn.index.html new file mode 100644 index 000000000..ba00514a5 --- /dev/null +++ b/arrayfire/core/index/fn.index.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.index.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.index_gen.html b/arrayfire/core/index/fn.index_gen.html new file mode 100644 index 000000000..0f200bdc1 --- /dev/null +++ b/arrayfire/core/index/fn.index_gen.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.index_gen.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.lookup.html b/arrayfire/core/index/fn.lookup.html new file mode 100644 index 000000000..70490cf7d --- /dev/null +++ b/arrayfire/core/index/fn.lookup.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.lookup.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.row.html b/arrayfire/core/index/fn.row.html new file mode 100644 index 000000000..284a0b6e2 --- /dev/null +++ b/arrayfire/core/index/fn.row.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.row.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.rows.html b/arrayfire/core/index/fn.rows.html new file mode 100644 index 000000000..57c43345a --- /dev/null +++ b/arrayfire/core/index/fn.rows.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.rows.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_col.html b/arrayfire/core/index/fn.set_col.html new file mode 100644 index 000000000..d8976e9a4 --- /dev/null +++ b/arrayfire/core/index/fn.set_col.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_col.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_cols.html b/arrayfire/core/index/fn.set_cols.html new file mode 100644 index 000000000..8cb51abce --- /dev/null +++ b/arrayfire/core/index/fn.set_cols.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_cols.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_row.html b/arrayfire/core/index/fn.set_row.html new file mode 100644 index 000000000..0d90f2fba --- /dev/null +++ b/arrayfire/core/index/fn.set_row.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_row.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_rows.html b/arrayfire/core/index/fn.set_rows.html new file mode 100644 index 000000000..61c36abec --- /dev/null +++ b/arrayfire/core/index/fn.set_rows.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_rows.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_slice.html b/arrayfire/core/index/fn.set_slice.html new file mode 100644 index 000000000..c0a71cda0 --- /dev/null +++ b/arrayfire/core/index/fn.set_slice.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_slice.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.set_slices.html b/arrayfire/core/index/fn.set_slices.html new file mode 100644 index 000000000..c46460895 --- /dev/null +++ b/arrayfire/core/index/fn.set_slices.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_slices.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.slice.html b/arrayfire/core/index/fn.slice.html new file mode 100644 index 000000000..53100ef90 --- /dev/null +++ b/arrayfire/core/index/fn.slice.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.slice.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/fn.slices.html b/arrayfire/core/index/fn.slices.html new file mode 100644 index 000000000..64e60c415 --- /dev/null +++ b/arrayfire/core/index/fn.slices.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.slices.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/struct.Indexer.html b/arrayfire/core/index/struct.Indexer.html new file mode 100644 index 000000000..f1d57d235 --- /dev/null +++ b/arrayfire/core/index/struct.Indexer.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Indexer.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/index/trait.Indexable.html b/arrayfire/core/index/trait.Indexable.html new file mode 100644 index 000000000..62c38bc2b --- /dev/null +++ b/arrayfire/core/index/trait.Indexable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.Indexable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.get_default_random_engine.html b/arrayfire/core/random/fn.get_default_random_engine.html new file mode 100644 index 000000000..76fc467f4 --- /dev/null +++ b/arrayfire/core/random/fn.get_default_random_engine.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_default_random_engine.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.get_seed.html b/arrayfire/core/random/fn.get_seed.html new file mode 100644 index 000000000..d39356c78 --- /dev/null +++ b/arrayfire/core/random/fn.get_seed.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_seed.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.randn.html b/arrayfire/core/random/fn.randn.html new file mode 100644 index 000000000..cda19f0e5 --- /dev/null +++ b/arrayfire/core/random/fn.randn.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.randn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.random_normal.html b/arrayfire/core/random/fn.random_normal.html new file mode 100644 index 000000000..c53d5a1c8 --- /dev/null +++ b/arrayfire/core/random/fn.random_normal.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.random_normal.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.random_uniform.html b/arrayfire/core/random/fn.random_uniform.html new file mode 100644 index 000000000..e5d9ddae7 --- /dev/null +++ b/arrayfire/core/random/fn.random_uniform.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.random_uniform.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.randu.html b/arrayfire/core/random/fn.randu.html new file mode 100644 index 000000000..8a8945e18 --- /dev/null +++ b/arrayfire/core/random/fn.randu.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.randu.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.set_default_random_engine_type.html b/arrayfire/core/random/fn.set_default_random_engine_type.html new file mode 100644 index 000000000..2236c8b1b --- /dev/null +++ b/arrayfire/core/random/fn.set_default_random_engine_type.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_default_random_engine_type.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/fn.set_seed.html b/arrayfire/core/random/fn.set_seed.html new file mode 100644 index 000000000..d866c712d --- /dev/null +++ b/arrayfire/core/random/fn.set_seed.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.set_seed.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/random/struct.RandomEngine.html b/arrayfire/core/random/struct.RandomEngine.html new file mode 100644 index 000000000..16b8782da --- /dev/null +++ b/arrayfire/core/random/struct.RandomEngine.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.RandomEngine.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/seq/struct.Seq.html b/arrayfire/core/seq/struct.Seq.html new file mode 100644 index 000000000..fc12ac1dd --- /dev/null +++ b/arrayfire/core/seq/struct.Seq.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/struct.Seq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/fn.alloc_host.html b/arrayfire/core/util/fn.alloc_host.html new file mode 100644 index 000000000..266ababc4 --- /dev/null +++ b/arrayfire/core/util/fn.alloc_host.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.alloc_host.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/fn.free_host.html b/arrayfire/core/util/fn.free_host.html new file mode 100644 index 000000000..10377e70f --- /dev/null +++ b/arrayfire/core/util/fn.free_host.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.free_host.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/fn.get_size.html b/arrayfire/core/util/fn.get_size.html new file mode 100644 index 000000000..f63e7b266 --- /dev/null +++ b/arrayfire/core/util/fn.get_size.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/fn.get_size.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ComplexFloating.html b/arrayfire/core/util/trait.ComplexFloating.html new file mode 100644 index 000000000..a104957cc --- /dev/null +++ b/arrayfire/core/util/trait.ComplexFloating.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ComplexFloating.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ConfidenceCCInput.html b/arrayfire/core/util/trait.ConfidenceCCInput.html new file mode 100644 index 000000000..58c5bfd26 --- /dev/null +++ b/arrayfire/core/util/trait.ConfidenceCCInput.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ConfidenceCCInput.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.CovarianceComputable.html b/arrayfire/core/util/trait.CovarianceComputable.html new file mode 100644 index 000000000..5ea553e25 --- /dev/null +++ b/arrayfire/core/util/trait.CovarianceComputable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.CovarianceComputable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.DeconvInput.html b/arrayfire/core/util/trait.DeconvInput.html new file mode 100644 index 000000000..a616a3494 --- /dev/null +++ b/arrayfire/core/util/trait.DeconvInput.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.DeconvInput.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.EdgeComputable.html b/arrayfire/core/util/trait.EdgeComputable.html new file mode 100644 index 000000000..0f3991f4c --- /dev/null +++ b/arrayfire/core/util/trait.EdgeComputable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.EdgeComputable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.FloatingPoint.html b/arrayfire/core/util/trait.FloatingPoint.html new file mode 100644 index 000000000..251a3bf3d --- /dev/null +++ b/arrayfire/core/util/trait.FloatingPoint.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.FloatingPoint.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.Fromf64.html b/arrayfire/core/util/trait.Fromf64.html new file mode 100644 index 000000000..4d7be13e0 --- /dev/null +++ b/arrayfire/core/util/trait.Fromf64.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.Fromf64.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.GrayRGBConvertible.html b/arrayfire/core/util/trait.GrayRGBConvertible.html new file mode 100644 index 000000000..07ddc7d8c --- /dev/null +++ b/arrayfire/core/util/trait.GrayRGBConvertible.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.GrayRGBConvertible.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.HasAfEnum.html b/arrayfire/core/util/trait.HasAfEnum.html new file mode 100644 index 000000000..687089377 --- /dev/null +++ b/arrayfire/core/util/trait.HasAfEnum.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.HasAfEnum.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ImageFilterType.html b/arrayfire/core/util/trait.ImageFilterType.html new file mode 100644 index 000000000..36c071bc1 --- /dev/null +++ b/arrayfire/core/util/trait.ImageFilterType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ImageFilterType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ImageNativeType.html b/arrayfire/core/util/trait.ImageNativeType.html new file mode 100644 index 000000000..a0715d1a3 --- /dev/null +++ b/arrayfire/core/util/trait.ImageNativeType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ImageNativeType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ImplicitPromote.html b/arrayfire/core/util/trait.ImplicitPromote.html new file mode 100644 index 000000000..30ac9e4fd --- /dev/null +++ b/arrayfire/core/util/trait.ImplicitPromote.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ImplicitPromote.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.IndexableType.html b/arrayfire/core/util/trait.IndexableType.html new file mode 100644 index 000000000..07cd39e11 --- /dev/null +++ b/arrayfire/core/util/trait.IndexableType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.IndexableType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.IntegralType.html b/arrayfire/core/util/trait.IntegralType.html new file mode 100644 index 000000000..b3d3fcfbc --- /dev/null +++ b/arrayfire/core/util/trait.IntegralType.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.IntegralType.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.MedianComputable.html b/arrayfire/core/util/trait.MedianComputable.html new file mode 100644 index 000000000..004211360 --- /dev/null +++ b/arrayfire/core/util/trait.MedianComputable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.MedianComputable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.MomentsComputable.html b/arrayfire/core/util/trait.MomentsComputable.html new file mode 100644 index 000000000..b0c3ab96b --- /dev/null +++ b/arrayfire/core/util/trait.MomentsComputable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.MomentsComputable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.RealFloating.html b/arrayfire/core/util/trait.RealFloating.html new file mode 100644 index 000000000..7298989f1 --- /dev/null +++ b/arrayfire/core/util/trait.RealFloating.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.RealFloating.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.RealNumber.html b/arrayfire/core/util/trait.RealNumber.html new file mode 100644 index 000000000..dc89152f4 --- /dev/null +++ b/arrayfire/core/util/trait.RealNumber.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.RealNumber.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.ReduceByKeyInput.html b/arrayfire/core/util/trait.ReduceByKeyInput.html new file mode 100644 index 000000000..8ba30dad3 --- /dev/null +++ b/arrayfire/core/util/trait.ReduceByKeyInput.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.ReduceByKeyInput.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/trait.Scanable.html b/arrayfire/core/util/trait.Scanable.html new file mode 100644 index 000000000..685fdc533 --- /dev/null +++ b/arrayfire/core/util/trait.Scanable.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/trait.Scanable.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_array.html b/arrayfire/core/util/type.af_array.html new file mode 100644 index 000000000..26ab3adcd --- /dev/null +++ b/arrayfire/core/util/type.af_array.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_array.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_event.html b/arrayfire/core/util/type.af_event.html new file mode 100644 index 000000000..844b09ade --- /dev/null +++ b/arrayfire/core/util/type.af_event.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_event.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_features.html b/arrayfire/core/util/type.af_features.html new file mode 100644 index 000000000..b16b88d4f --- /dev/null +++ b/arrayfire/core/util/type.af_features.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_features.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_index_t.html b/arrayfire/core/util/type.af_index_t.html new file mode 100644 index 000000000..ba5846703 --- /dev/null +++ b/arrayfire/core/util/type.af_index_t.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_index_t.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_random_engine.html b/arrayfire/core/util/type.af_random_engine.html new file mode 100644 index 000000000..0b6f21a86 --- /dev/null +++ b/arrayfire/core/util/type.af_random_engine.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_random_engine.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.af_window.html b/arrayfire/core/util/type.af_window.html new file mode 100644 index 000000000..2f55857d2 --- /dev/null +++ b/arrayfire/core/util/type.af_window.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.af_window.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.c32.html b/arrayfire/core/util/type.c32.html new file mode 100644 index 000000000..eed92556c --- /dev/null +++ b/arrayfire/core/util/type.c32.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.c32.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.c64.html b/arrayfire/core/util/type.c64.html new file mode 100644 index 000000000..a07676969 --- /dev/null +++ b/arrayfire/core/util/type.c64.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.c64.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.dim_t.html b/arrayfire/core/util/type.dim_t.html new file mode 100644 index 000000000..05b1f9705 --- /dev/null +++ b/arrayfire/core/util/type.dim_t.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.dim_t.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.u64_t.html b/arrayfire/core/util/type.u64_t.html new file mode 100644 index 000000000..3b5e9ff6b --- /dev/null +++ b/arrayfire/core/util/type.u64_t.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.u64_t.html...

+ + + \ No newline at end of file diff --git a/arrayfire/core/util/type.void_ptr.html b/arrayfire/core/util/type.void_ptr.html new file mode 100644 index 000000000..7b4c11b69 --- /dev/null +++ b/arrayfire/core/util/type.void_ptr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../../arrayfire/type.void_ptr.html...

+ + + \ No newline at end of file diff --git a/arrayfire/enum.AfError.html b/arrayfire/enum.AfError.html new file mode 100644 index 000000000..c92a1bdc2 --- /dev/null +++ b/arrayfire/enum.AfError.html @@ -0,0 +1,77 @@ +arrayfire::AfError - Rust + + + +

[][src]Enum arrayfire::AfError

#[repr(u32)]pub enum AfError {
+    SUCCESS,
+    ERR_NO_MEM,
+    ERR_DRIVER,
+    ERR_RUNTIME,
+    ERR_INVALID_ARRAY,
+    ERR_ARG,
+    ERR_SIZE,
+    ERR_TYPE,
+    ERR_DIFF_TYPE,
+    ERR_BATCH,
+    ERR_DEVICE,
+    ERR_NOT_SUPPORTED,
+    ERR_NOT_CONFIGURED,
+    ERR_NO_DBL,
+    ERR_NO_GFX,
+    ERR_INTERNAL,
+    ERR_UNKNOWN,
+}

Error codes

+

+ Variants

+
SUCCESS

The function returned successfully

+
ERR_NO_MEM

The system or device ran out of memory

+
ERR_DRIVER

There was an error in the device driver

+
ERR_RUNTIME

There was an error with the runtime environment

+
ERR_INVALID_ARRAY

The input array is not a valid Array object

+
ERR_ARG

One of the function arguments is incorrect

+
ERR_SIZE

The size is incorrect

+
ERR_TYPE

The type is not suppported by this function

+
ERR_DIFF_TYPE

The type of the input arrays are not compatible

+
ERR_BATCH

Function does not support GFOR / batch mode

+
ERR_DEVICE

Input does not belong to the current device

+
ERR_NOT_SUPPORTED

The option is not supported

+
ERR_NOT_CONFIGURED

This build of ArrayFire does not support this feature

+
ERR_NO_DBL

This device does not support double

+
ERR_NO_GFX

This build of ArrayFire was not built with graphics or this device does +not support graphics

+
ERR_INTERNAL

There was an internal error either in ArrayFire or in a project +upstream

+
ERR_UNKNOWN

Unknown Error

+

Trait Implementations

impl Clone for AfError[src]

impl Copy for AfError[src]

impl Debug for AfError[src]

impl Display for AfError[src]

impl From<i32> for AfError[src]

impl PartialEq<AfError> for AfError[src]

impl StructuralPartialEq for AfError[src]

Auto Trait Implementations

impl RefUnwindSafe for AfError

impl Send for AfError

impl Sync for AfError

impl Unpin for AfError

impl UnwindSafe for AfError

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.Backend.html b/arrayfire/enum.Backend.html new file mode 100644 index 000000000..375d75200 --- /dev/null +++ b/arrayfire/enum.Backend.html @@ -0,0 +1,48 @@ +arrayfire::Backend - Rust + + + +

[][src]Enum arrayfire::Backend

#[repr(u32)]pub enum Backend {
+    DEFAULT,
+    CPU,
+    CUDA,
+    OPENCL,
+}

Compute/Acceleration Backend

+

+ Variants

+
DEFAULT

Default backend order: OpenCL -> CUDA -> CPU

+
CPU

CPU a.k.a sequential algorithms

+
CUDA

CUDA Compute Backend

+
OPENCL

OpenCL Compute Backend

+

Trait Implementations

impl Clone for Backend[src]

impl Copy for Backend[src]

impl Debug for Backend[src]

impl Display for Backend[src]

impl PartialEq<Backend> for Backend[src]

impl StructuralPartialEq for Backend[src]

Auto Trait Implementations

impl RefUnwindSafe for Backend

impl Send for Backend

impl Sync for Backend

impl Unpin for Backend

impl UnwindSafe for Backend

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.BinaryOp.html b/arrayfire/enum.BinaryOp.html new file mode 100644 index 000000000..038ffddf3 --- /dev/null +++ b/arrayfire/enum.BinaryOp.html @@ -0,0 +1,47 @@ +arrayfire::BinaryOp - Rust + + + +

[][src]Enum arrayfire::BinaryOp

#[repr(u32)]pub enum BinaryOp {
+    ADD,
+    MUL,
+    MIN,
+    MAX,
+}

Binary operation types for generalized scan functions

+

+ Variants

+
ADD

Addition operation

+
MUL

Multiplication operation

+
MIN

Minimum operation

+
MAX

Maximum operation

+

Trait Implementations

impl Clone for BinaryOp[src]

impl Copy for BinaryOp[src]

impl Debug for BinaryOp[src]

impl From<u32> for BinaryOp[src]

impl PartialEq<BinaryOp> for BinaryOp[src]

impl StructuralPartialEq for BinaryOp[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.BorderType.html b/arrayfire/enum.BorderType.html new file mode 100644 index 000000000..4d6976874 --- /dev/null +++ b/arrayfire/enum.BorderType.html @@ -0,0 +1,46 @@ +arrayfire::BorderType - Rust + + + +

[][src]Enum arrayfire::BorderType

#[repr(u32)]pub enum BorderType {
+    ZERO,
+    SYMMETRIC,
+    CLAMP_TO_EDGE,
+    PERIODIC,
+}

Helps determine how to pad kernels along borders

+

+ Variants

+
ZERO

Pad using zeros

+
SYMMETRIC

Pad using mirrored values along border

+
CLAMP_TO_EDGE

Out of bound values are clamped to the edge

+
PERIODIC

Out of bound values are mapped to range of the dimension in cyclic fashion

+

Trait Implementations

impl Clone for BorderType[src]

impl Copy for BorderType[src]

impl Debug for BorderType[src]

impl PartialEq<BorderType> for BorderType[src]

impl StructuralPartialEq for BorderType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.CannyThresholdType.html b/arrayfire/enum.CannyThresholdType.html new file mode 100644 index 000000000..461fbc309 --- /dev/null +++ b/arrayfire/enum.CannyThresholdType.html @@ -0,0 +1,42 @@ +arrayfire::CannyThresholdType - Rust + + + +

[][src]Enum arrayfire::CannyThresholdType

#[repr(u32)]pub enum CannyThresholdType {
+    MANUAL,
+    OTSU,
+}

Canny edge detector threshold operations types

+

+ Variants

+
MANUAL

User has to define canny thresholds manually

+
OTSU

Determine canny algorithm high threshold using Otsu algorithm automatically

+

Trait Implementations

impl Clone for CannyThresholdType[src]

impl Copy for CannyThresholdType[src]

impl Debug for CannyThresholdType[src]

impl PartialEq<CannyThresholdType> for CannyThresholdType[src]

impl StructuralPartialEq for CannyThresholdType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.ColorMap.html b/arrayfire/enum.ColorMap.html new file mode 100644 index 000000000..2b952a37a --- /dev/null +++ b/arrayfire/enum.ColorMap.html @@ -0,0 +1,53 @@ +arrayfire::ColorMap - Rust + + + +

[][src]Enum arrayfire::ColorMap

#[repr(u32)]pub enum ColorMap {
+    DEFAULT,
+    SPECTRUM,
+    COLORS,
+    RED,
+    MOOD,
+    HEAT,
+    BLUE,
+}

Dictates what color map is used for Image rendering

+

+ Variants

+
DEFAULT

Default color map is grayscale range [0-1]

+
SPECTRUM

Visible spectrum color map

+
COLORS

Colors

+
RED

Red hue map

+
MOOD

Mood color map

+
HEAT

Heat color map

+
BLUE

Blue hue map

+

Trait Implementations

impl Clone for ColorMap[src]

impl Copy for ColorMap[src]

impl Debug for ColorMap[src]

impl From<u32> for ColorMap[src]

impl PartialEq<ColorMap> for ColorMap[src]

impl StructuralPartialEq for ColorMap[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.ColorSpace.html b/arrayfire/enum.ColorSpace.html new file mode 100644 index 000000000..8d8c749aa --- /dev/null +++ b/arrayfire/enum.ColorSpace.html @@ -0,0 +1,44 @@ +arrayfire::ColorSpace - Rust + + + +

[][src]Enum arrayfire::ColorSpace

#[repr(u32)]pub enum ColorSpace {
+    GRAY,
+    RGB,
+    HSV,
+}

Identify the color space of given image(Array)

+

+ Variants

+
GRAY

Grayscale color space

+
RGB

Red-Green-Blue color space

+
HSV

Hue-Saturation-value color space

+

Trait Implementations

impl Clone for ColorSpace[src]

impl Copy for ColorSpace[src]

impl Debug for ColorSpace[src]

impl PartialEq<ColorSpace> for ColorSpace[src]

impl StructuralPartialEq for ColorSpace[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.Connectivity.html b/arrayfire/enum.Connectivity.html new file mode 100644 index 000000000..24b98b5ee --- /dev/null +++ b/arrayfire/enum.Connectivity.html @@ -0,0 +1,42 @@ +arrayfire::Connectivity - Rust + + + +

[][src]Enum arrayfire::Connectivity

#[repr(u32)]pub enum Connectivity {
+    FOUR,
+    EIGHT,
+}

Used by regions function to identify type of connectivity

+

+ Variants

+
FOUR

North-East-South-West (N-E-S-W) connectivity from given pixel/point

+
EIGHT

N-NE-E-SE-S-SW-W-NW connectivity from given pixel/point

+

Trait Implementations

impl Clone for Connectivity[src]

impl Copy for Connectivity[src]

impl Debug for Connectivity[src]

impl PartialEq<Connectivity> for Connectivity[src]

impl StructuralPartialEq for Connectivity[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.ConvDomain.html b/arrayfire/enum.ConvDomain.html new file mode 100644 index 000000000..f19a7eec7 --- /dev/null +++ b/arrayfire/enum.ConvDomain.html @@ -0,0 +1,45 @@ +arrayfire::ConvDomain - Rust + + + +

[][src]Enum arrayfire::ConvDomain

#[repr(u32)]pub enum ConvDomain {
+    AUTO,
+    SPATIAL,
+    FREQUENCY,
+}

Helps determine if convolution is in Spatial or Frequency domain

+

+ Variants

+
AUTO

ArrayFire chooses whether the convolution will be in spatial domain or frequency domain

+
SPATIAL

Convoltion in spatial domain

+
FREQUENCY

Convolution in frequency domain

+

Trait Implementations

impl Clone for ConvDomain[src]

impl Copy for ConvDomain[src]

impl Debug for ConvDomain[src]

impl From<u32> for ConvDomain[src]

impl PartialEq<ConvDomain> for ConvDomain[src]

impl StructuralPartialEq for ConvDomain[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.ConvGradientType.html b/arrayfire/enum.ConvGradientType.html new file mode 100644 index 000000000..a4d5f99a1 --- /dev/null +++ b/arrayfire/enum.ConvGradientType.html @@ -0,0 +1,46 @@ +arrayfire::ConvGradientType - Rust + + + +

[][src]Enum arrayfire::ConvGradientType

#[repr(u32)]pub enum ConvGradientType {
+    FILTER,
+    DATA,
+    BIAS,
+    DEFAULT,
+}

Gradient mode for convolution

+

+ Variants

+
FILTER

Filter Gradient

+
DATA

Data Gradient

+
BIAS

Biased Gradient

+
DEFAULT

Default is Data Gradient

+

Trait Implementations

impl Clone for ConvGradientType[src]

impl Copy for ConvGradientType[src]

impl Debug for ConvGradientType[src]

impl PartialEq<ConvGradientType> for ConvGradientType[src]

impl StructuralPartialEq for ConvGradientType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.ConvMode.html b/arrayfire/enum.ConvMode.html new file mode 100644 index 000000000..4acce9c3d --- /dev/null +++ b/arrayfire/enum.ConvMode.html @@ -0,0 +1,43 @@ +arrayfire::ConvMode - Rust + + + +

[][src]Enum arrayfire::ConvMode

#[repr(u32)]pub enum ConvMode {
+    DEFAULT,
+    EXPAND,
+}

Helps determine the size of output of convolution

+

+ Variants

+
DEFAULT

Default convolution mode where output size is same as input size

+
EXPAND

Output of convolution is expanded based on signal and filter sizes

+

Trait Implementations

impl Clone for ConvMode[src]

impl Copy for ConvMode[src]

impl Debug for ConvMode[src]

impl From<u32> for ConvMode[src]

impl PartialEq<ConvMode> for ConvMode[src]

impl StructuralPartialEq for ConvMode[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.CublasMathMode.html b/arrayfire/enum.CublasMathMode.html new file mode 100644 index 000000000..125d83ec6 --- /dev/null +++ b/arrayfire/enum.CublasMathMode.html @@ -0,0 +1,42 @@ +arrayfire::CublasMathMode - Rust + + + +

[][src]Enum arrayfire::CublasMathMode

#[repr(u32)]pub enum CublasMathMode {
+    TENSOR_OP,
+    DEFAULT,
+}

Gradient mode for convolution

+

+ Variants

+
TENSOR_OP

To indicate use of Tensor Cores on CUDA capable GPUs

+
DEFAULT

Default i.e. tensor core operations will be avoided by the library

+

Trait Implementations

impl Clone for CublasMathMode[src]

impl Copy for CublasMathMode[src]

impl Debug for CublasMathMode[src]

impl PartialEq<CublasMathMode> for CublasMathMode[src]

impl StructuralPartialEq for CublasMathMode[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.DType.html b/arrayfire/enum.DType.html new file mode 100644 index 000000000..55f847603 --- /dev/null +++ b/arrayfire/enum.DType.html @@ -0,0 +1,65 @@ +arrayfire::DType - Rust + + + +

[][src]Enum arrayfire::DType

#[repr(u32)]pub enum DType {
+    F32,
+    C32,
+    F64,
+    C64,
+    B8,
+    S32,
+    U32,
+    U8,
+    S64,
+    U64,
+    S16,
+    U16,
+    F16,
+}

Types of Array data type

+

+ Variants

+
F32

32 bit float

+
C32

32 bit complex float

+
F64

64 bit float

+
C64

64 bit complex float

+
B8

8 bit boolean

+
S32

32 bit signed integer

+
U32

32 bit unsigned integer

+
U8

8 bit unsigned integer

+
S64

64 bit signed integer

+
U64

64 bit unsigned integer

+
S16

16 bit signed integer

+
U16

16 bit unsigned integer

+
F16

16 bit floating point

+

Trait Implementations

impl Clone for DType[src]

impl Copy for DType[src]

impl Debug for DType[src]

impl From<u32> for DType[src]

impl PartialEq<DType> for DType[src]

impl StructuralPartialEq for DType[src]

Auto Trait Implementations

impl RefUnwindSafe for DType

impl Send for DType

impl Sync for DType

impl Unpin for DType

impl UnwindSafe for DType

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.DiffusionEq.html b/arrayfire/enum.DiffusionEq.html new file mode 100644 index 000000000..43076da13 --- /dev/null +++ b/arrayfire/enum.DiffusionEq.html @@ -0,0 +1,44 @@ +arrayfire::DiffusionEq - Rust + + + +

[][src]Enum arrayfire::DiffusionEq

#[repr(u32)]pub enum DiffusionEq {
+    QUADRATIC,
+    EXPONENTIAL,
+    DEFAULT,
+}

Anisotropic diffusion flux equation types

+

+ Variants

+
QUADRATIC

Quadratic flux function

+
EXPONENTIAL

Exponential flux function

+
DEFAULT

Default flux function, a.k.a exponential

+

Trait Implementations

impl Clone for DiffusionEq[src]

impl Copy for DiffusionEq[src]

impl Debug for DiffusionEq[src]

impl PartialEq<DiffusionEq> for DiffusionEq[src]

impl StructuralPartialEq for DiffusionEq[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.FluxFn.html b/arrayfire/enum.FluxFn.html new file mode 100644 index 000000000..3c1756b4f --- /dev/null +++ b/arrayfire/enum.FluxFn.html @@ -0,0 +1,44 @@ +arrayfire::FluxFn - Rust + + + +

[][src]Enum arrayfire::FluxFn

#[repr(u32)]pub enum FluxFn {
+    GRADIENT,
+    MCDE,
+    DEFAULT,
+}

Diffusion equation types

+

+ Variants

+
GRADIENT

Quadratic flux function

+
MCDE

Modified curvature diffusion equation

+
DEFAULT

Default diffusion method, Gradient

+

Trait Implementations

impl Clone for FluxFn[src]

impl Copy for FluxFn[src]

impl Debug for FluxFn[src]

impl PartialEq<FluxFn> for FluxFn[src]

impl StructuralPartialEq for FluxFn[src]

Auto Trait Implementations

impl RefUnwindSafe for FluxFn

impl Send for FluxFn

impl Sync for FluxFn

impl Unpin for FluxFn

impl UnwindSafe for FluxFn

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.HomographyType.html b/arrayfire/enum.HomographyType.html new file mode 100644 index 000000000..80a472fd4 --- /dev/null +++ b/arrayfire/enum.HomographyType.html @@ -0,0 +1,42 @@ +arrayfire::HomographyType - Rust + + + +

[][src]Enum arrayfire::HomographyType

#[repr(u32)]pub enum HomographyType {
+    RANSAC,
+    LMEDS,
+}

Homography type

+

+ Variants

+
RANSAC

RANdom SAmple Consensus algorithm

+
LMEDS

Least Median of Squares

+

Trait Implementations

impl Clone for HomographyType[src]

impl Copy for HomographyType[src]

impl Debug for HomographyType[src]

impl PartialEq<HomographyType> for HomographyType[src]

impl StructuralPartialEq for HomographyType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.InterpType.html b/arrayfire/enum.InterpType.html new file mode 100644 index 000000000..ed9c71ea6 --- /dev/null +++ b/arrayfire/enum.InterpType.html @@ -0,0 +1,59 @@ +arrayfire::InterpType - Rust + + + +

[][src]Enum arrayfire::InterpType

#[repr(u32)]pub enum InterpType {
+    NEAREST,
+    LINEAR,
+    BILINEAR,
+    CUBIC,
+    LOWER,
+    LINEAR_COSINE,
+    BILINEAR_COSINE,
+    BICUBIC,
+    CUBIC_SPLINE,
+    BICUBIC_SPLINE,
+}

Dictates the interpolation method to be used by a function

+

+ Variants

+
NEAREST

Nearest Neighbor interpolation method

+
LINEAR

Linear interpolation method

+
BILINEAR

Bilinear interpolation method

+
CUBIC

Cubic interpolation method

+
LOWER

Floor indexed

+
LINEAR_COSINE

Linear interpolation with cosine smoothing

+
BILINEAR_COSINE

Bilinear interpolation with cosine smoothing

+
BICUBIC

Bicubic interpolation

+
CUBIC_SPLINE

Cubic interpolation with Catmull-Rom splines

+
BICUBIC_SPLINE

Bicubic interpolation with Catmull-Rom splines

+

Trait Implementations

impl Clone for InterpType[src]

impl Copy for InterpType[src]

impl Debug for InterpType[src]

impl From<u32> for InterpType[src]

impl PartialEq<InterpType> for InterpType[src]

impl StructuralPartialEq for InterpType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.InverseDeconvAlgo.html b/arrayfire/enum.InverseDeconvAlgo.html new file mode 100644 index 000000000..d038738df --- /dev/null +++ b/arrayfire/enum.InverseDeconvAlgo.html @@ -0,0 +1,42 @@ +arrayfire::InverseDeconvAlgo - Rust + + + +

[][src]Enum arrayfire::InverseDeconvAlgo

#[repr(u32)]pub enum InverseDeconvAlgo {
+    TIKHONOV,
+    DEFAULT,
+}

Inverse Deconvolution Algorithm

+

+ Variants

+
TIKHONOV

Tikhonov algorithm

+
DEFAULT

Default is Tikhonov algorithm

+

Trait Implementations

impl Clone for InverseDeconvAlgo[src]

impl Copy for InverseDeconvAlgo[src]

impl Debug for InverseDeconvAlgo[src]

impl PartialEq<InverseDeconvAlgo> for InverseDeconvAlgo[src]

impl StructuralPartialEq for InverseDeconvAlgo[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.IterativeDeconvAlgo.html b/arrayfire/enum.IterativeDeconvAlgo.html new file mode 100644 index 000000000..26e38d305 --- /dev/null +++ b/arrayfire/enum.IterativeDeconvAlgo.html @@ -0,0 +1,44 @@ +arrayfire::IterativeDeconvAlgo - Rust + + + +

[][src]Enum arrayfire::IterativeDeconvAlgo

#[repr(u32)]pub enum IterativeDeconvAlgo {
+    LANDWEBER,
+    RICHARDSONLUCY,
+    DEFAULT,
+}

Iterative Deconvolution Algorithm

+

+ Variants

+
LANDWEBER

Land-Weber Algorithm

+
RICHARDSONLUCY

Richardson-Lucy Algorithm

+
DEFAULT

Default is Land-Weber algorithm

+

Trait Implementations

impl Clone for IterativeDeconvAlgo[src]

impl Copy for IterativeDeconvAlgo[src]

impl Debug for IterativeDeconvAlgo[src]

impl PartialEq<IterativeDeconvAlgo> for IterativeDeconvAlgo[src]

impl StructuralPartialEq for IterativeDeconvAlgo[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.MarkerType.html b/arrayfire/enum.MarkerType.html new file mode 100644 index 000000000..dca38973a --- /dev/null +++ b/arrayfire/enum.MarkerType.html @@ -0,0 +1,54 @@ +arrayfire::MarkerType - Rust + + + +

[][src]Enum arrayfire::MarkerType

#[repr(u32)]pub enum MarkerType {
+    NONE,
+    POINT,
+    CIRCLE,
+    SQUARE,
+    TRIANGLE,
+    CROSS,
+    PLUS,
+    STAR,
+}

Plotting markers

+

+ Variants

+
NONE

No marker

+
POINT

Pointer marker

+
CIRCLE

Hollow circle marker

+
SQUARE

Hollow Square marker

+
TRIANGLE

Hollow Triangle marker

+
CROSS

Cross-hair marker

+
PLUS

Plus symbol marker

+
STAR

Start symbol marker

+

Trait Implementations

impl Clone for MarkerType[src]

impl Copy for MarkerType[src]

impl Debug for MarkerType[src]

impl PartialEq<MarkerType> for MarkerType[src]

impl StructuralPartialEq for MarkerType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.MatProp.html b/arrayfire/enum.MatProp.html new file mode 100644 index 000000000..4f85674a9 --- /dev/null +++ b/arrayfire/enum.MatProp.html @@ -0,0 +1,65 @@ +arrayfire::MatProp - Rust + + + +

[][src]Enum arrayfire::MatProp

#[repr(u32)]pub enum MatProp {
+    NONE,
+    TRANS,
+    CTRANS,
+    CONJ,
+    UPPER,
+    LOWER,
+    DIAGUNIT,
+    SYM,
+    POSDEF,
+    ORTHOG,
+    TRIDIAG,
+    BLOCKDIAG,
+}

Helps determine the type of a Matrix

+

+ Variants

+
NONE

Default (no-op)

+
TRANS

Data needs to be transposed

+
CTRANS

Data needs to be conjugate transposed

+
CONJ

Matrix is upper triangular

+
UPPER

Matrix needs to be conjugate

+
LOWER

Matrix is lower triangular

+
DIAGUNIT

Matrix diagonal has unitary values

+
SYM

Matrix is symmetric

+
POSDEF

Matrix is positive definite

+
ORTHOG

Matrix is orthogonal

+
TRIDIAG

Matrix is tri-diagonal

+
BLOCKDIAG

Matrix is block-diagonal

+

Trait Implementations

impl BitOr<MatProp> for MatProp[src]

type Output = Self

The resulting type after applying the | operator.

+

impl Clone for MatProp[src]

impl Copy for MatProp[src]

impl Debug for MatProp[src]

impl From<u32> for MatProp[src]

impl PartialEq<MatProp> for MatProp[src]

impl StructuralPartialEq for MatProp[src]

Auto Trait Implementations

impl RefUnwindSafe for MatProp

impl Send for MatProp

impl Sync for MatProp

impl Unpin for MatProp

impl UnwindSafe for MatProp

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.MatchType.html b/arrayfire/enum.MatchType.html new file mode 100644 index 000000000..5e6d7c852 --- /dev/null +++ b/arrayfire/enum.MatchType.html @@ -0,0 +1,57 @@ +arrayfire::MatchType - Rust + + + +

[][src]Enum arrayfire::MatchType

#[repr(u32)]pub enum MatchType {
+    SAD,
+    ZSAD,
+    LSAD,
+    SSD,
+    ZSSD,
+    LSSD,
+    NCC,
+    ZNCC,
+    SHD,
+}

Error metric used by matchTemplate function

+

+ Variants

+
SAD

Sum of Absolute Differences

+
ZSAD

Zero-mean Sum of Absolute Differences

+
LSAD

Locally scaled Sum of Absolute Differences

+
SSD

Sum of Squared Differences

+
ZSSD

Zero-mean Sum of Squared Differences

+
LSSD

Localy scaled Sum of Squared Differences

+
NCC

Normalized Cross Correlation

+
ZNCC

Zero-mean Normalized Cross Correlation

+
SHD

Sum of Hamming Distances

+

Trait Implementations

impl Clone for MatchType[src]

impl Copy for MatchType[src]

impl Debug for MatchType[src]

impl From<u32> for MatchType[src]

impl PartialEq<MatchType> for MatchType[src]

impl StructuralPartialEq for MatchType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.MomentType.html b/arrayfire/enum.MomentType.html new file mode 100644 index 000000000..7f7c995f8 --- /dev/null +++ b/arrayfire/enum.MomentType.html @@ -0,0 +1,48 @@ +arrayfire::MomentType - Rust + + + +

[][src]Enum arrayfire::MomentType

#[repr(u32)]pub enum MomentType {
+    M00,
+    M01,
+    M10,
+    M11,
+    FIRST_ORDER,
+}

Image moment types

+

+ Variants

+
M00

Central moment of order (0 + 0)

+
M01

Central moment of order (0 + 1)

+
M10

Central moment of order (1 + 0)

+
M11

Central moment of order (1 + 1)

+
FIRST_ORDER

All central moments of order (0,0), (0,1), (1,0) and (1,1)

+

Trait Implementations

impl Clone for MomentType[src]

impl Copy for MomentType[src]

impl Debug for MomentType[src]

impl PartialEq<MomentType> for MomentType[src]

impl StructuralPartialEq for MomentType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.NormType.html b/arrayfire/enum.NormType.html new file mode 100644 index 000000000..b89500086 --- /dev/null +++ b/arrayfire/enum.NormType.html @@ -0,0 +1,54 @@ +arrayfire::NormType - Rust + + + +

[][src]Enum arrayfire::NormType

#[repr(u32)]pub enum NormType {
+    VECTOR_1,
+    VECTOR_INF,
+    VECTOR_2,
+    VECTOR_P,
+    MATRIX_1,
+    MATRIX_INF,
+    MATRIX_2,
+    MATRIX_L_PQ,
+}

Norm type

+

+ Variants

+
VECTOR_1

Treats input as a vector and return sum of absolute values

+
VECTOR_INF

Treats input as vector and return max of absolute values

+
VECTOR_2

Treats input as vector and returns euclidean norm

+
VECTOR_P

Treats input as vector and returns the p-norm

+
MATRIX_1

Return the max of column sums

+
MATRIX_INF

Return the max of row sums

+
MATRIX_2

Returns the max singular value (Currently not supported)

+
MATRIX_L_PQ

Returns Lpq-norm

+

Trait Implementations

impl Clone for NormType[src]

impl Copy for NormType[src]

impl Debug for NormType[src]

impl PartialEq<NormType> for NormType[src]

impl StructuralPartialEq for NormType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.RandomEngineType.html b/arrayfire/enum.RandomEngineType.html new file mode 100644 index 000000000..f33993757 --- /dev/null +++ b/arrayfire/enum.RandomEngineType.html @@ -0,0 +1,45 @@ +arrayfire::RandomEngineType - Rust + + + +

[][src]Enum arrayfire::RandomEngineType

#[repr(u32)]pub enum RandomEngineType {
+    PHILOX_4X32_10,
+    THREEFRY_2X32_16,
+    MERSENNE_GP11213,
+}

Random engine types

+

+ Variants

+
PHILOX_4X32_10

Philox variant with N=4, W=32 and Rounds=10

+
THREEFRY_2X32_16

Threefry variant with N=2, W=32 and Rounds=16

+
MERSENNE_GP11213

Mersenne variant with MEXP = 11213

+

Trait Implementations

impl Clone for RandomEngineType[src]

impl Copy for RandomEngineType[src]

impl Debug for RandomEngineType[src]

impl From<u32> for RandomEngineType[src]

impl PartialEq<RandomEngineType> for RandomEngineType[src]

impl StructuralPartialEq for RandomEngineType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.Scalar.html b/arrayfire/enum.Scalar.html new file mode 100644 index 000000000..7c969ddc0 --- /dev/null +++ b/arrayfire/enum.Scalar.html @@ -0,0 +1,62 @@ +arrayfire::Scalar - Rust + + + +

[][src]Enum arrayfire::Scalar

pub enum Scalar {
+    F32(f32),
+    C32(Complex<f32>),
+    F64(f64),
+    C64(Complex<f64>),
+    B8(bool),
+    S32(i32),
+    U32(u32),
+    U8(u8),
+    S64(i64),
+    U64(u64),
+    S16(i16),
+    U16(u16),
+}

Scalar value types

+

+ Variants

+
F32(f32)

32 bit float

+
C32(Complex<f32>)

32 bit complex float

+
F64(f64)

64 bit float

+
C64(Complex<f64>)

64 bit complex float

+
B8(bool)

8 bit boolean

+
S32(i32)

32 bit signed integer

+
U32(u32)

32 bit unsigned integer

+
U8(u8)

8 bit unsigned integer

+
S64(i64)

64 bit signed integer

+
U64(u64)

64 bit unsigned integer

+
S16(i16)

16 bit signed integer

+
U16(u16)

16 bit unsigned integer

+

Trait Implementations

impl Clone for Scalar[src]

impl Copy for Scalar[src]

impl Debug for Scalar[src]

impl PartialEq<Scalar> for Scalar[src]

impl StructuralPartialEq for Scalar[src]

Auto Trait Implementations

impl RefUnwindSafe for Scalar

impl Send for Scalar

impl Sync for Scalar

impl Unpin for Scalar

impl UnwindSafe for Scalar

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.SparseFormat.html b/arrayfire/enum.SparseFormat.html new file mode 100644 index 000000000..60588a08a --- /dev/null +++ b/arrayfire/enum.SparseFormat.html @@ -0,0 +1,47 @@ +arrayfire::SparseFormat - Rust + + + +

[][src]Enum arrayfire::SparseFormat

#[repr(u32)]pub enum SparseFormat {
+    DENSE,
+    CSR,
+    CSC,
+    COO,
+}

Sparse storage format type

+

+ Variants

+
DENSE

Dense format

+
CSR

Compressed sparse row format

+
CSC

Compressed sparse coloumn format

+
COO

Coordinate list (row, coloumn, value) tuples.

+

Trait Implementations

impl Clone for SparseFormat[src]

impl Copy for SparseFormat[src]

impl Debug for SparseFormat[src]

impl From<u32> for SparseFormat[src]

impl PartialEq<SparseFormat> for SparseFormat[src]

impl StructuralPartialEq for SparseFormat[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.TopkFn.html b/arrayfire/enum.TopkFn.html new file mode 100644 index 000000000..609a58a15 --- /dev/null +++ b/arrayfire/enum.TopkFn.html @@ -0,0 +1,44 @@ +arrayfire::TopkFn - Rust + + + +

[][src]Enum arrayfire::TopkFn

#[repr(u32)]pub enum TopkFn {
+    MIN,
+    MAX,
+    DEFAULT,
+}

topk function ordering

+

+ Variants

+
MIN

Top k min values

+
MAX

Top k max values

+
DEFAULT

Default option(max)

+

Trait Implementations

impl Clone for TopkFn[src]

impl Copy for TopkFn[src]

impl Debug for TopkFn[src]

impl PartialEq<TopkFn> for TopkFn[src]

impl StructuralPartialEq for TopkFn[src]

Auto Trait Implementations

impl RefUnwindSafe for TopkFn

impl Send for TopkFn

impl Sync for TopkFn

impl Unpin for TopkFn

impl UnwindSafe for TopkFn

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.VarianceBias.html b/arrayfire/enum.VarianceBias.html new file mode 100644 index 000000000..f49d1b498 --- /dev/null +++ b/arrayfire/enum.VarianceBias.html @@ -0,0 +1,44 @@ +arrayfire::VarianceBias - Rust + + + +

[][src]Enum arrayfire::VarianceBias

#[repr(u32)]pub enum VarianceBias {
+    SAMPLE,
+    POPULATION,
+    DEFAULT,
+}

Gradient mode for convolution

+

+ Variants

+
SAMPLE

Sample variance

+
POPULATION

Population variance

+
DEFAULT

Default (Population) variance

+

Trait Implementations

impl Clone for VarianceBias[src]

impl Copy for VarianceBias[src]

impl Debug for VarianceBias[src]

impl PartialEq<VarianceBias> for VarianceBias[src]

impl StructuralPartialEq for VarianceBias[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/enum.YCCStd.html b/arrayfire/enum.YCCStd.html new file mode 100644 index 000000000..9b5273adf --- /dev/null +++ b/arrayfire/enum.YCCStd.html @@ -0,0 +1,44 @@ +arrayfire::YCCStd - Rust + + + +

[][src]Enum arrayfire::YCCStd

#[repr(u32)]pub enum YCCStd {
+    YCC_601,
+    YCC_709,
+    YCC_2020,
+}

YCbCr Standards

+

+ Variants

+
YCC_601

ITU-R BT.601 (formerly CCIR 601) standard

+
YCC_709

ITU-R BT.709 standard

+
YCC_2020

ITU-R BT.2020 standard

+

Trait Implementations

impl Clone for YCCStd[src]

impl Copy for YCCStd[src]

impl Debug for YCCStd[src]

impl PartialEq<YCCStd> for YCCStd[src]

impl StructuralPartialEq for YCCStd[src]

Auto Trait Implementations

impl RefUnwindSafe for YCCStd

impl Send for YCCStd

impl Sync for YCCStd

impl Unpin for YCCStd

impl UnwindSafe for YCCStd

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/fn.HANDLE_ERROR.html b/arrayfire/fn.HANDLE_ERROR.html new file mode 100644 index 000000000..f5807a6b0 --- /dev/null +++ b/arrayfire/fn.HANDLE_ERROR.html @@ -0,0 +1,16 @@ +arrayfire::HANDLE_ERROR - Rust + + + +

[][src]Function arrayfire::HANDLE_ERROR

pub fn HANDLE_ERROR(error_code: AfError)

Default error handler for error code returned by ArrayFire FFI calls

+
\ No newline at end of file diff --git a/arrayfire/fn.abs.html b/arrayfire/fn.abs.html new file mode 100644 index 000000000..b6acd3573 --- /dev/null +++ b/arrayfire/fn.abs.html @@ -0,0 +1,17 @@ +arrayfire::abs - Rust + + + +

[][src]Function arrayfire::abs

pub fn abs<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Computes absolute value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.accum.html b/arrayfire/fn.accum.html new file mode 100644 index 000000000..17cb6f9f8 --- /dev/null +++ b/arrayfire/fn.accum.html @@ -0,0 +1,33 @@ +arrayfire::accum - Rust + + + +

[][src]Function arrayfire::accum

pub fn accum<T>(input: &Array<T>, dim: i32) -> Array<T::AggregateOutType> where
    T: HasAfEnum,
    T::AggregateOutType: HasAfEnum

Perform exclusive sum of elements along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the exclusive scan operation is carried out
  • +
+

Return Values

+

Result Array with exclusive sums of input Array elements along a given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, accum};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = accum(&a, 0);
+print(&b);
+let c = accum(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.acos.html b/arrayfire/fn.acos.html new file mode 100644 index 000000000..db38c584c --- /dev/null +++ b/arrayfire/fn.acos.html @@ -0,0 +1,17 @@ +arrayfire::acos - Rust + + + +

[][src]Function arrayfire::acos

pub fn acos<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute acos

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.acosh.html b/arrayfire/fn.acosh.html new file mode 100644 index 000000000..91f594aaf --- /dev/null +++ b/arrayfire/fn.acosh.html @@ -0,0 +1,17 @@ +arrayfire::acosh - Rust + + + +

[][src]Function arrayfire::acosh

pub fn acosh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute acosh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.add.html b/arrayfire/fn.add.html new file mode 100644 index 000000000..01151e7cb --- /dev/null +++ b/arrayfire/fn.add.html @@ -0,0 +1,46 @@ +arrayfire::add - Rust + + + +

[][src]Function arrayfire::add

pub fn add<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Addition of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.all_true.html b/arrayfire/fn.all_true.html new file mode 100644 index 000000000..5816e2821 --- /dev/null +++ b/arrayfire/fn.all_true.html @@ -0,0 +1,33 @@ +arrayfire::all_true - Rust + + + +

[][src]Function arrayfire::all_true

pub fn all_true<T>(input: &Array<T>, dim: i32) -> Array<bool> where
    T: HasAfEnum,
    bool: HasAfEnum

Find if all of the values along a given dimension in the Array are true

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the predicate is evaluated
  • +
+

Return Values

+

Result Array that contains the result of AND operation of all elements along given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, all_true};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = all_true(&a, 0);
+print(&b);
+let c = all_true(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.all_true_all.html b/arrayfire/fn.all_true_all.html new file mode 100644 index 000000000..f9a47e1bf --- /dev/null +++ b/arrayfire/fn.all_true_all.html @@ -0,0 +1,29 @@ +arrayfire::all_true_all - Rust + + + +

[][src]Function arrayfire::all_true_all

pub fn all_true_all<T>(input: &Array<T>) -> (bool, bool) where
    T: HasAfEnum,
    bool: HasAfEnum + Fromf64

Find if all values of Array are non-zero

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the result of AND operation on all values of Array.

+

Examples

+
+use arrayfire::{Dim4, print, randu, all_true_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", all_true_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.all_true_by_key.html b/arrayfire/fn.all_true_by_key.html new file mode 100644 index 000000000..a995c681f --- /dev/null +++ b/arrayfire/fn.all_true_by_key.html @@ -0,0 +1,37 @@ +arrayfire::all_true_by_key - Rust + + + +

[][src]Function arrayfire::all_true_by_key

pub fn all_true_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Key based AND of elements along a given dimension

+

All positive non-zero values are considered true, while negative and zero +values are considered as false.

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+

Examples

+
+use arrayfire::{Dim4, print, randu, all_true_by_key};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let vals = randu::<f32>(dims);
+let keys = randu::<u32>(Dim4::new(&[5, 1, 1, 1]));
+print(&vals);
+print(&keys);
+let (out_keys, out_vals) = all_true_by_key(&keys, &vals, 0);
+print(&out_keys);
+print(&out_vals);
+
\ No newline at end of file diff --git a/arrayfire/fn.alloc_host.html b/arrayfire/fn.alloc_host.html new file mode 100644 index 000000000..bb69eaa78 --- /dev/null +++ b/arrayfire/fn.alloc_host.html @@ -0,0 +1,16 @@ +arrayfire::alloc_host - Rust + + + +

[][src]Function arrayfire::alloc_host

pub fn alloc_host<T>(elements: usize, _type: DType) -> *const T

Allocates space using Arrayfire allocator in host memory

+
\ No newline at end of file diff --git a/arrayfire/fn.alloc_pinned.html b/arrayfire/fn.alloc_pinned.html new file mode 100644 index 000000000..d31b62e50 --- /dev/null +++ b/arrayfire/fn.alloc_pinned.html @@ -0,0 +1,16 @@ +arrayfire::alloc_pinned - Rust + + + +

[][src]Function arrayfire::alloc_pinned

pub unsafe fn alloc_pinned(bytes: usize) -> void_ptr

Allocate non-pageable memory on HOST memory

+
\ No newline at end of file diff --git a/arrayfire/fn.and.html b/arrayfire/fn.and.html new file mode 100644 index 000000000..d3a0dc31e --- /dev/null +++ b/arrayfire/fn.and.html @@ -0,0 +1,33 @@ +arrayfire::and - Rust + + + +

[][src]Function arrayfire::and

pub fn and<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise logical and operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.anisotropic_diffusion.html b/arrayfire/fn.anisotropic_diffusion.html new file mode 100644 index 000000000..f359a087a --- /dev/null +++ b/arrayfire/fn.anisotropic_diffusion.html @@ -0,0 +1,80 @@ +arrayfire::anisotropic_diffusion - Rust + + + +

[][src]Function arrayfire::anisotropic_diffusion

pub fn anisotropic_diffusion<T>(
    img: &Array<T>,
    dt: f32,
    k: f32,
    iters: u32,
    fftype: FluxFn,
    diff_kind: DiffusionEq
) -> Array<T::AbsOutType> where
    T: HasAfEnum + EdgeComputable,
    T::AbsOutType: HasAfEnum

Anisotropic smoothing filter

+

Anisotropic diffusion algorithm aims at removing noise in the images +while preserving important features such as edges. The algorithm +essentially creates a scale space representation of the original +image, where image from previous step is used to create a new version +of blurred image using the diffusion process. Standard isotropic diffusion +methods such as gaussian blur, doesn't take into account the local +content(smaller neighborhood of current processing pixel) while removing +noise. Anisotropic diffusion uses the flux equations given below to +achieve that. Flux equation is the formula used by the diffusion process +to determine how much a pixel in neighborhood should contribute to +the blurring operation being done at the current pixel at a given iteration.

+

The flux function can be either exponential or quadratic.

+ + + + + + + + + + +
Available Flux Functions
+ AF_FLUX_QUADRATIC + + \begin{equation} + \frac{1}{1 + (\frac{\| \nabla I\|}{K})^2} + \end{equation} +
+ AF_FLUX_EXPONENTIAL + + \begin{equation} + \exp{-(\frac{\| \nabla I\|}{K})^2} + \end{equation} +
+

Please be cautious using the time step parameter to the function. +Appropriate time steps for solving this type of p.d.e. depend on +the dimensionality of the image and the order of the equation. +Stable values for most 2D and 3D functions are 0.125 and 0.0625, +respectively. The time step values are automatically constrained +to the stable value.

+

Another input parameter to be cautious about is the conductance +parameter, lower values strongly preserve image features and +vice-versa. For human vision, this value ranges from 0.5 to 2.0.

+

Parameters

+
    +
  • img is the noisy input image
  • +
  • dt is the timestep for diffusion equation
  • +
  • k is the conductance parameter for diffusion
  • +
  • iters is the number of iterations diffusion is performed
  • +
  • fftype dictates the type of flux flow and it is an +enum
  • +
  • diff_kind dictates the type of diffusion and it is an +enum
  • +
+

Return Values

+

Returns an anisotropically smoothed and noise-free image

+

References

+
    +
  • Pietro Perona and Jitendra Malik, Scale-space and edge detection using anisotropic diffusion, IEEE Transactions on Pattern Analysis +Machine Intelligence, vol. 12, pp. 629-639, 1990.
  • +
  • R. Whitaker and X. Xue. Variable-Conductance, Level-Set Curvature for Image Denoising, International Conference on Image Processing, +2001 pp. 142-145, Vol.3.
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.any_true.html b/arrayfire/fn.any_true.html new file mode 100644 index 000000000..a5d6d0162 --- /dev/null +++ b/arrayfire/fn.any_true.html @@ -0,0 +1,33 @@ +arrayfire::any_true - Rust + + + +

[][src]Function arrayfire::any_true

pub fn any_true<T>(input: &Array<T>, dim: i32) -> Array<bool> where
    T: HasAfEnum,
    bool: HasAfEnum

Find if any of the values along a given dimension in the Array are true

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the predicate is evaluated
  • +
+

Return Values

+

Result Array that contains the result of OR operation of all elements along given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, any_true};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = any_true(&a, 0);
+print(&b);
+let c = any_true(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.any_true_all.html b/arrayfire/fn.any_true_all.html new file mode 100644 index 000000000..87fd4e2f4 --- /dev/null +++ b/arrayfire/fn.any_true_all.html @@ -0,0 +1,29 @@ +arrayfire::any_true_all - Rust + + + +

[][src]Function arrayfire::any_true_all

pub fn any_true_all<T>(input: &Array<T>) -> (bool, bool) where
    T: HasAfEnum,
    bool: HasAfEnum + Fromf64

Find if any value of Array is non-zero

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the result of OR operation on all values of Array.

+

Examples

+
+use arrayfire::{Dim4, print, randu, any_true_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", any_true_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.any_true_by_key.html b/arrayfire/fn.any_true_by_key.html new file mode 100644 index 000000000..3ef9c7011 --- /dev/null +++ b/arrayfire/fn.any_true_by_key.html @@ -0,0 +1,37 @@ +arrayfire::any_true_by_key - Rust + + + +

[][src]Function arrayfire::any_true_by_key

pub fn any_true_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Key based OR of elements along a given dimension

+

All positive non-zero values are considered true, while negative and zero +values are considered as false.

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+

Examples

+
+use arrayfire::{Dim4, print, randu, any_true_by_key};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let vals = randu::<f32>(dims);
+let keys = randu::<u32>(Dim4::new(&[5, 1, 1, 1]));
+print(&vals);
+print(&keys);
+let (out_keys, out_vals) = any_true_by_key(&keys, &vals, 0);
+print(&out_keys);
+print(&out_vals);
+
\ No newline at end of file diff --git a/arrayfire/fn.approx1.html b/arrayfire/fn.approx1.html new file mode 100644 index 000000000..a832178f7 --- /dev/null +++ b/arrayfire/fn.approx1.html @@ -0,0 +1,26 @@ +arrayfire::approx1 - Rust + + + +

[][src]Function arrayfire::approx1

pub fn approx1<T, P>(
    input: &Array<T>,
    pos: &Array<P>,
    method: InterpType,
    off_grid: f32
) -> Array<T> where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Perform signal interpolation for 1d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • pos Array contains the interpolation locations
  • +
  • method indicates the type of interpolation method that be used. It is of type enum +InterpType
  • +
  • off_grid is the value that will set in the output Array when certain index is out of bounds
  • +
+

Return Values

+

An Array with interpolated values

+
\ No newline at end of file diff --git a/arrayfire/fn.approx1_uniform.html b/arrayfire/fn.approx1_uniform.html new file mode 100644 index 000000000..c11c94300 --- /dev/null +++ b/arrayfire/fn.approx1_uniform.html @@ -0,0 +1,29 @@ +arrayfire::approx1_uniform - Rust + + + +

[][src]Function arrayfire::approx1_uniform

pub fn approx1_uniform<T, P>(
    input: &Array<T>,
    pos: &Array<P>,
    interp_dim: i32,
    start: f64,
    step: f64,
    method: InterpType,
    off_grid: f32
) -> Array<T> where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Perform signal interpolation for 1d signals along specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • pos Array contains the interpolation locations
  • +
  • interp_dim is the dimension along which interpolation is performed
  • +
  • start is the first index along interp_dim
  • +
  • step is the uniform spacing value between subsequent indices along interp_dim
  • +
  • method indicates the type of interpolation method that be used. It is of type enum +InterpType
  • +
  • off_grid is the value that will set in the output Array when certain index is out of bounds
  • +
+

Return Values

+

An Array with interpolated values

+
\ No newline at end of file diff --git a/arrayfire/fn.approx1_uniform_v2.html b/arrayfire/fn.approx1_uniform_v2.html new file mode 100644 index 000000000..49bf93e19 --- /dev/null +++ b/arrayfire/fn.approx1_uniform_v2.html @@ -0,0 +1,16 @@ +arrayfire::approx1_uniform_v2 - Rust + + + +

[][src]Function arrayfire::approx1_uniform_v2

pub fn approx1_uniform_v2<T, P>(
    output: &mut Array<T>,
    input: &Array<T>,
    pos: &Array<P>,
    interp_dim: i32,
    start: f64,
    step: f64,
    method: InterpType,
    off_grid: f32
) where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Same as approx1_uniform but uses existing Array as output

+
\ No newline at end of file diff --git a/arrayfire/fn.approx1_v2.html b/arrayfire/fn.approx1_v2.html new file mode 100644 index 000000000..45d72387c --- /dev/null +++ b/arrayfire/fn.approx1_v2.html @@ -0,0 +1,16 @@ +arrayfire::approx1_v2 - Rust + + + +

[][src]Function arrayfire::approx1_v2

pub fn approx1_v2<T, P>(
    output: &mut Array<T>,
    input: &Array<T>,
    pos: &Array<P>,
    method: InterpType,
    off_grid: f32
) where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Same as approx1 but uses existing Array as output

+
\ No newline at end of file diff --git a/arrayfire/fn.approx2.html b/arrayfire/fn.approx2.html new file mode 100644 index 000000000..983cb9eaa --- /dev/null +++ b/arrayfire/fn.approx2.html @@ -0,0 +1,27 @@ +arrayfire::approx2 - Rust + + + +

[][src]Function arrayfire::approx2

pub fn approx2<T, P>(
    input: &Array<T>,
    pos0: &Array<P>,
    pos1: &Array<P>,
    method: InterpType,
    off_grid: f32
) -> Array<T> where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Perform signal interpolation for 2d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • pos0 Array contains the interpolation locations for first dimension
  • +
  • pos1 Array contains the interpolation locations for second dimension
  • +
  • method indicates the type of interpolation method that be used. It is of type enum +InterpType
  • +
  • off_grid is the value that will set in the output Array when certain index is out of bounds
  • +
+

Return Values

+

An Array with interpolated values

+
\ No newline at end of file diff --git a/arrayfire/fn.approx2_uniform.html b/arrayfire/fn.approx2_uniform.html new file mode 100644 index 000000000..15e6d3bc2 --- /dev/null +++ b/arrayfire/fn.approx2_uniform.html @@ -0,0 +1,33 @@ +arrayfire::approx2_uniform - Rust + + + +

[][src]Function arrayfire::approx2_uniform

pub fn approx2_uniform<T, P>(
    input: &Array<T>,
    pos0: &Array<P>,
    interp_dim0: i32,
    start0: f64,
    step0: f64,
    pos1: &Array<P>,
    interp_dim1: i32,
    start1: f64,
    step1: f64,
    method: InterpType,
    off_grid: f32
) -> Array<T> where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Perform signal interpolation for 2d signals along a specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • pos0 Array contains the interpolation locations for first dimension
  • +
  • interp_dim0 is the dimension along which interpolation is performed
  • +
  • start0 is the first index along interp_dim0
  • +
  • step0 is the uniform spacing value between subsequent indices along interp_dim0
  • +
  • pos1 Array contains the interpolation locations for second dimension
  • +
  • interp_dim0 is the dimension along which interpolation is performed
  • +
  • start0 is the first index along interp_dim1
  • +
  • step0 is the uniform spacing value between subsequent indices along interp_dim1
  • +
  • method indicates the type of interpolation method that be used. It is of type enum +InterpType
  • +
  • off_grid is the value that will set in the output Array when certain index is out of bounds
  • +
+

Return Values

+

An Array with interpolated values

+
\ No newline at end of file diff --git a/arrayfire/fn.approx2_uniform_v2.html b/arrayfire/fn.approx2_uniform_v2.html new file mode 100644 index 000000000..a9345d155 --- /dev/null +++ b/arrayfire/fn.approx2_uniform_v2.html @@ -0,0 +1,16 @@ +arrayfire::approx2_uniform_v2 - Rust + + + +

[][src]Function arrayfire::approx2_uniform_v2

pub fn approx2_uniform_v2<T, P>(
    output: &mut Array<T>,
    input: &Array<T>,
    pos0: &Array<P>,
    interp_dim0: i32,
    start0: f64,
    step0: f64,
    pos1: &Array<P>,
    interp_dim1: i32,
    start1: f64,
    step1: f64,
    method: InterpType,
    off_grid: f32
) where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Same as approx2_uniform but uses existing Array as output

+
\ No newline at end of file diff --git a/arrayfire/fn.approx2_v2.html b/arrayfire/fn.approx2_v2.html new file mode 100644 index 000000000..758973329 --- /dev/null +++ b/arrayfire/fn.approx2_v2.html @@ -0,0 +1,16 @@ +arrayfire::approx2_v2 - Rust + + + +

[][src]Function arrayfire::approx2_v2

pub fn approx2_v2<T, P>(
    output: &mut Array<T>,
    input: &Array<T>,
    pos0: &Array<P>,
    pos1: &Array<P>,
    method: InterpType,
    off_grid: f32
) where
    T: HasAfEnum + FloatingPoint,
    P: HasAfEnum + RealFloating

Same as approx2 but uses existing Array as output

+
\ No newline at end of file diff --git a/arrayfire/fn.arg.html b/arrayfire/fn.arg.html new file mode 100644 index 000000000..5a463c068 --- /dev/null +++ b/arrayfire/fn.arg.html @@ -0,0 +1,17 @@ +arrayfire::arg - Rust + + + +

[][src]Function arrayfire::arg

pub fn arg<T: HasAfEnum>(input: &Array<T>) -> Array<T::ArgOutType> where
    T::ArgOutType: HasAfEnum

Computes phase value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.asin.html b/arrayfire/fn.asin.html new file mode 100644 index 000000000..0cc949c3d --- /dev/null +++ b/arrayfire/fn.asin.html @@ -0,0 +1,17 @@ +arrayfire::asin - Rust + + + +

[][src]Function arrayfire::asin

pub fn asin<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute asin

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.asinh.html b/arrayfire/fn.asinh.html new file mode 100644 index 000000000..e027b1b45 --- /dev/null +++ b/arrayfire/fn.asinh.html @@ -0,0 +1,17 @@ +arrayfire::asinh - Rust + + + +

[][src]Function arrayfire::asinh

pub fn asinh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute asinh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.assign_gen.html b/arrayfire/fn.assign_gen.html new file mode 100644 index 000000000..5cf698264 --- /dev/null +++ b/arrayfire/fn.assign_gen.html @@ -0,0 +1,44 @@ +arrayfire::assign_gen - Rust + + + +

[][src]Function arrayfire::assign_gen

pub fn assign_gen<T>(lhs: &mut Array<T>, indices: &Indexer<'_>, rhs: &Array<T>) where
    T: HasAfEnum

Assign an Array to another after indexing it using any combination of Array's and Sequence's

+

Examples

+
+use arrayfire::{Array, Dim4, Seq, print, randu, constant, Indexer, assign_gen};
+let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+let seq4gen = Seq::new(0.0, 2.0, 1.0);
+let mut a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+// [5 3 1 1]
+//     0.0000     0.2190     0.3835
+//     0.1315     0.0470     0.5194
+//     0.7556     0.6789     0.8310
+//     0.4587     0.6793     0.0346
+//     0.5328     0.9347     0.0535
+
+let b    = constant(2.0 as f32, Dim4::new(&[3, 3, 1, 1]));
+
+let mut idxrs = Indexer::default();
+idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
+idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
+
+assign_gen(&mut a, &idxrs, &b);
+println!("a(indices, seq(0, 2, 1))"); print(&a);
+// [5 3 1 1]
+//     0.0000     0.2190     0.3835
+//     2.0000     2.0000     2.0000
+//     2.0000     2.0000     2.0000
+//     2.0000     2.0000     2.0000
+//     0.5328     0.9347     0.0535
+
\ No newline at end of file diff --git a/arrayfire/fn.assign_seq.html b/arrayfire/fn.assign_seq.html new file mode 100644 index 000000000..09453c691 --- /dev/null +++ b/arrayfire/fn.assign_seq.html @@ -0,0 +1,38 @@ +arrayfire::assign_seq - Rust + + + +

[][src]Function arrayfire::assign_seq

pub fn assign_seq<T, I>(lhs: &mut Array<I>, seqs: &[Seq<T>], rhs: &Array<I>) where
    c_double: From<T>,
    I: HasAfEnum,
    T: Copy + IndexableType

Assign(copy) content of an Array to another Array indexed by Sequences

+

Assign rhs to lhs after indexing lhs

+

Examples

+
+use arrayfire::{constant, Dim4, Seq, assign_seq, print};
+let mut a = constant(2.0 as f32, Dim4::new(&[5, 3, 1, 1]));
+print(&a);
+// 2.0 2.0 2.0
+// 2.0 2.0 2.0
+// 2.0 2.0 2.0
+// 2.0 2.0 2.0
+// 2.0 2.0 2.0
+
+let b    = constant(1.0 as f32, Dim4::new(&[3, 3, 1, 1]));
+let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
+assign_seq(&mut a, seqs, &b);
+
+print(&a);
+// 2.0 2.0 2.0
+// 1.0 1.0 1.0
+// 1.0 1.0 1.0
+// 1.0 1.0 1.0
+// 2.0 2.0 2.0
+
\ No newline at end of file diff --git a/arrayfire/fn.atan.html b/arrayfire/fn.atan.html new file mode 100644 index 000000000..e5156c5e9 --- /dev/null +++ b/arrayfire/fn.atan.html @@ -0,0 +1,17 @@ +arrayfire::atan - Rust + + + +

[][src]Function arrayfire::atan

pub fn atan<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute atan

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.atan2.html b/arrayfire/fn.atan2.html new file mode 100644 index 000000000..b9f82acb1 --- /dev/null +++ b/arrayfire/fn.atan2.html @@ -0,0 +1,46 @@ +arrayfire::atan2 - Rust + + + +

[][src]Function arrayfire::atan2

pub fn atan2<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Calculate atan2 of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.atanh.html b/arrayfire/fn.atanh.html new file mode 100644 index 000000000..59897603f --- /dev/null +++ b/arrayfire/fn.atanh.html @@ -0,0 +1,17 @@ +arrayfire::atanh - Rust + + + +

[][src]Function arrayfire::atanh

pub fn atanh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute atanh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.bilateral.html b/arrayfire/fn.bilateral.html new file mode 100644 index 000000000..ba92d0386 --- /dev/null +++ b/arrayfire/fn.bilateral.html @@ -0,0 +1,30 @@ +arrayfire::bilateral - Rust + + + +

[][src]Function arrayfire::bilateral

pub fn bilateral<T>(
    input: &Array<T>,
    spatial_sigma: f32,
    chromatic_sigma: f32,
    iscolor: bool
) -> Array<T::AbsOutType> where
    T: HasAfEnum + ImageFilterType,
    T::AbsOutType: HasAfEnum

Bilateral Filter.

+

A bilateral filter is a edge-preserving filter that reduces noise in an image. The intensity of +each pixel is replaced by a weighted average of the intensities of nearby pixels. The weights +follow a Gaussian distribution and depend on the distance as well as the color distance.

+

The bilateral filter requires the size of the filter (in pixels) and the upper bound on color +values, N, where pixel values range from 0–N inclusively.

+

Parameters

+
    +
  • input array is the input image
  • +
  • spatial_sigma is the spatial variance parameter that decides the filter window
  • +
  • chromatic_sigma is the chromatic variance parameter
  • +
  • iscolor indicates if the input is color image or grayscale
  • +
+

Return Values

+

Filtered Image - Array

+
\ No newline at end of file diff --git a/arrayfire/fn.bitand.html b/arrayfire/fn.bitand.html new file mode 100644 index 000000000..e3e09aa86 --- /dev/null +++ b/arrayfire/fn.bitand.html @@ -0,0 +1,33 @@ +arrayfire::bitand - Rust + + + +

[][src]Function arrayfire::bitand

pub fn bitand<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise AND(bit) operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.bitnot.html b/arrayfire/fn.bitnot.html new file mode 100644 index 000000000..abde4ea4d --- /dev/null +++ b/arrayfire/fn.bitnot.html @@ -0,0 +1,16 @@ +arrayfire::bitnot - Rust + + + +

[][src]Function arrayfire::bitnot

pub fn bitnot<T: HasAfEnum>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum + IntegralType

Perform bitwise complement on all values of Array

+
\ No newline at end of file diff --git a/arrayfire/fn.bitor.html b/arrayfire/fn.bitor.html new file mode 100644 index 000000000..38a6d0300 --- /dev/null +++ b/arrayfire/fn.bitor.html @@ -0,0 +1,33 @@ +arrayfire::bitor - Rust + + + +

[][src]Function arrayfire::bitor

pub fn bitor<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise OR(bit) operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.bitxor.html b/arrayfire/fn.bitxor.html new file mode 100644 index 000000000..2416ff2ca --- /dev/null +++ b/arrayfire/fn.bitxor.html @@ -0,0 +1,33 @@ +arrayfire::bitxor - Rust + + + +

[][src]Function arrayfire::bitxor

pub fn bitxor<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise XOR(bit) operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.canny.html b/arrayfire/fn.canny.html new file mode 100644 index 000000000..c25040079 --- /dev/null +++ b/arrayfire/fn.canny.html @@ -0,0 +1,29 @@ +arrayfire::canny - Rust + + + +

[][src]Function arrayfire::canny

pub fn canny<T>(
    input: &Array<T>,
    threshold_type: CannyThresholdType,
    low: f32,
    high: f32,
    sobel_window: u32,
    is_fast: bool
) -> Array<bool> where
    T: HasAfEnum + EdgeComputable

Canny edge detection operator

+

The Canny edge detector is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images. A more in depth discussion on it can be found here.

+

Parameters

+
    +
  • input is the input image
  • +
  • threshold_type helps determine if user set high threshold is to be used or not. It can take values defined by the enum CannyThresholdType
  • +
  • low is the lower threshold % of the maximum or auto-derived high
  • +
  • high is the higher threshold % of maximum value in gradient image used in hysteresis procedure. This value is ignored if CannyThresholdType::OTSU is chosen.
  • +
  • sobel_window is the window size of sobel kernel for computing gradient direction and magnitude.
  • +
  • is_fast indicates if L1 norm(faster but less accurate) is used to compute image gradient magnitude instead of L2 norm.
  • +
+

Return Values

+

An Array of binary type DType::B8 indicating edges(All pixels with +non-zero values are edges).

+
\ No newline at end of file diff --git a/arrayfire/fn.cbrt.html b/arrayfire/fn.cbrt.html new file mode 100644 index 000000000..93d927b6f --- /dev/null +++ b/arrayfire/fn.cbrt.html @@ -0,0 +1,17 @@ +arrayfire::cbrt - Rust + + + +

[][src]Function arrayfire::cbrt

pub fn cbrt<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute the cube root

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.ceil.html b/arrayfire/fn.ceil.html new file mode 100644 index 000000000..f68caacd0 --- /dev/null +++ b/arrayfire/fn.ceil.html @@ -0,0 +1,17 @@ +arrayfire::ceil - Rust + + + +

[][src]Function arrayfire::ceil

pub fn ceil<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Ceil the values in an Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.cholesky.html b/arrayfire/fn.cholesky.html new file mode 100644 index 000000000..70f8cba51 --- /dev/null +++ b/arrayfire/fn.cholesky.html @@ -0,0 +1,26 @@ +arrayfire::cholesky - Rust + + + +

[][src]Function arrayfire::cholesky

pub fn cholesky<T>(input: &Array<T>, is_upper: bool) -> (Array<T>, i32) where
    T: HasAfEnum + FloatingPoint

Perform Cholesky decomposition

+

Parameters

+
    +
  • input is the input matrix
  • +
  • is_upper is a boolean to indicate if the output has to be upper or lower triangular matrix
  • +
+

Return Values

+

A tuple of an Array and signed 32-bit integer.

+

The Array contains the triangular matrix (multiply it with conjugate transpose to reproduce the input).

+

If the integer is 0, it means the cholesky decomposition passed. Otherwise, it will contain the rank at +which the decomposition failed.

+
\ No newline at end of file diff --git a/arrayfire/fn.cholesky_inplace.html b/arrayfire/fn.cholesky_inplace.html new file mode 100644 index 000000000..8332fe5ec --- /dev/null +++ b/arrayfire/fn.cholesky_inplace.html @@ -0,0 +1,24 @@ +arrayfire::cholesky_inplace - Rust + + + +

[][src]Function arrayfire::cholesky_inplace

pub fn cholesky_inplace<T>(input: &mut Array<T>, is_upper: bool) -> i32 where
    T: HasAfEnum + FloatingPoint

Perform inplace Cholesky decomposition

+

Parameters

+
    +
  • input contains the input matrix on entry, and triangular matrix on exit.
  • +
  • is_upper is a boolean to indicate if the output has to be upper or lower triangular matrix
  • +
+

Return Values

+

A signed 32-bit integer. If the integer is 0, it means the cholesky decomposition passed. Otherwise, +it will contain the rank at which the decomposition failed.

+
\ No newline at end of file diff --git a/arrayfire/fn.clamp.html b/arrayfire/fn.clamp.html new file mode 100644 index 000000000..72fe8fd05 --- /dev/null +++ b/arrayfire/fn.clamp.html @@ -0,0 +1,45 @@ +arrayfire::clamp - Rust + + + +

[][src]Function arrayfire::clamp

pub fn clamp<T, C>(
    input: &Array<T>,
    arg1: &C,
    arg2: &C,
    batch: bool
) -> Array<<T as ImplicitPromote<<C as Convertable>::OutType>>::Output> where
    T: ImplicitPromote<<C as Convertable>::OutType>,
    C: Convertable,
    <C as Convertable>::OutType: ImplicitPromote<T>, 

Clamp the values of Array

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.col.html b/arrayfire/fn.col.html new file mode 100644 index 000000000..4765b43f7 --- /dev/null +++ b/arrayfire/fn.col.html @@ -0,0 +1,24 @@ +arrayfire::col - Rust + + + +

[][src]Function arrayfire::col

pub fn col<T>(input: &Array<T>, col_num: i64) -> Array<T> where
    T: HasAfEnum

Extract col_num col from input Array

+

Examples

+
+use arrayfire::{Dim4, randu, col, print};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Grab last col of the random matrix");
+print(&col(&a, 4));
+
\ No newline at end of file diff --git a/arrayfire/fn.color_space.html b/arrayfire/fn.color_space.html new file mode 100644 index 000000000..e5834df44 --- /dev/null +++ b/arrayfire/fn.color_space.html @@ -0,0 +1,44 @@ +arrayfire::color_space - Rust + + + +

[][src]Function arrayfire::color_space

pub fn color_space<T>(
    input: &Array<T>,
    tospace: ColorSpace,
    fromspace: ColorSpace
) -> Array<T> where
    T: HasAfEnum + RealNumber

Color space conversion

+

Following are the supported conversions

+
    +
  • RGB => GRAY
  • +
  • GRAY => RGB
  • +
  • RGB => HSV
  • +
  • HSV => RGB
  • +
  • YCbCr => RGB
  • +
  • RGB => YCbCr
  • +
+

RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores +individual values for red, green and blue, and hence the 3 values per pixel. A combination of +these three values produces the gamut of unique colors.

+

HSV (Hue, Saturation, Value), also known as HSB (hue, saturation, brightness), is often used by +artists because it is more natural to think about a color in terms of hue and saturation than +in terms of additive or subtractive color components (as in RGB). HSV is a transformation of +RGB colorspace; its components and colorimetry are relative to the RGB colorspace from which it +was derived. Like RGB, HSV also uses 3 values per pixel.

+

GRAY is a single channel color space where pixel value ranges from 0 to 1. Zero represents +black, one represent white and any value between zero & one is a gray value

+

Parameters

+
    +
  • input is the input image
  • +
  • tospace is the target color space. Takes values of ColorSpace
  • +
  • fromspace is the source image color space. Takes values of +ColorSpace
  • +
+

Return Values

+

An Array with input image values in target color space

+
\ No newline at end of file diff --git a/arrayfire/fn.cols.html b/arrayfire/fn.cols.html new file mode 100644 index 000000000..b2fb44f05 --- /dev/null +++ b/arrayfire/fn.cols.html @@ -0,0 +1,16 @@ +arrayfire::cols - Rust + + + +

[][src]Function arrayfire::cols

pub fn cols<T>(input: &Array<T>, first: i64, last: i64) -> Array<T> where
    T: HasAfEnum

Get all cols from first to last in the input Array

+
\ No newline at end of file diff --git a/arrayfire/fn.confidence_cc.html b/arrayfire/fn.confidence_cc.html new file mode 100644 index 000000000..aadf9fc27 --- /dev/null +++ b/arrayfire/fn.confidence_cc.html @@ -0,0 +1,52 @@ +arrayfire::confidence_cc - Rust + + + +

[][src]Function arrayfire::confidence_cc

pub fn confidence_cc<InOutType>(
    input: &Array<InOutType>,
    seedx: &Array<u32>,
    seedy: &Array<u32>,
    radius: u32,
    multiplier: u32,
    iterations: u32,
    segmented_val: f64
) -> Array<InOutType> where
    InOutType: ConfidenceCCInput

Segment image based on similar pixel characteristics

+

This filter is similar to regions with additional criteria for +segmentation. In regions, all connected pixels are considered to be a single component. +In this variation of connected components, pixels having similar pixel statistics of the +neighborhoods around a given set of seed points are grouped together.

+

The parameter radius determines the size of neighborhood around a seed point.

+

Mean and Variance are the pixel statistics that are computed across all neighborhoods around +the given set of seed points. The pixels which are connected to seed points and lie in the +confidence interval are grouped together. Given below is the confidence interval.

+

\begin{equation} +[\mu - \alpha * \sigma, \mu + \alpha * \sigma] +\end{equation} +where

+
    +
  • $ \mu $ is the mean of the pixels in the seed neighborhood
  • +
  • $ \sigma^2 $ is the variance of the pixels in the seed neighborhood
  • +
  • $ \alpha $ is the multiplier used to control the width of the confidence interval.
  • +
+

This filter follows an iterative approach for fine tuning the segmentation. An initial +segmenetation followed by a finite number iterations of segmentations are performed. +The user provided parameter iterations is only a request and the algorithm can prempt +the execution if variance approaches zero. The initial segmentation uses the mean and +variance calculated from the neighborhoods of all the seed points. For subsequent +segmentations, all pixels in the previous segmentation are used to re-calculate the mean +and variance (as opposed to using the pixels in the neighborhood of the seed point).

+

Parameters

+
    +
  • input is the input image
  • +
  • seedx contains the x coordinates of seeds in image coordinates
  • +
  • seedy contains the y coordinates of seeds in image coordinates
  • +
  • radius is the neighborhood region to be considered around each seed point
  • +
  • multiplier controls the threshold range computed from the mean and variance of seed point neighborhoods
  • +
  • iterations is the number of times the segmentation in performed
  • +
  • segmented_value is the value to which output array valid pixels are set to
  • +
+

Return Values

+

Segmented(based on pixel characteristics) image(Array) with regions surrounding the seed points

+
\ No newline at end of file diff --git a/arrayfire/fn.conjg.html b/arrayfire/fn.conjg.html new file mode 100644 index 000000000..f3964811d --- /dev/null +++ b/arrayfire/fn.conjg.html @@ -0,0 +1,17 @@ +arrayfire::conjg - Rust + + + +

[][src]Function arrayfire::conjg

pub fn conjg<T: HasAfEnum>(input: &Array<T>) -> Array<T::ComplexOutType> where
    T::ComplexOutType: HasAfEnum

Compute the complex conjugate

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.constant.html b/arrayfire/fn.constant.html new file mode 100644 index 000000000..e6befe428 --- /dev/null +++ b/arrayfire/fn.constant.html @@ -0,0 +1,37 @@ +arrayfire::constant - Rust + + + +

[][src]Function arrayfire::constant

pub fn constant<T>(cnst: T, dims: Dim4) -> Array<T> where
    T: ConstGenerator<OutType = T>, 

Create an Array with constant value

+

The trait ConstGenerator has been defined internally for the following types:

+
    +
  • i64
  • +
  • u64
  • +
  • num::Complex<f32> a.k.a c32
  • +
  • num::Complex<f64> a.k.a c64
  • +
  • f32
  • +
  • f64
  • +
  • i32
  • +
  • u32
  • +
  • u8
  • +
  • i16
  • +
  • u16
  • +
+

Parameters

+
    +
  • cnst is the constant value to be filled in the Array
  • +
  • dims is the size of the constant Array
  • +
+

Return Values

+

An Array of given dimensions with constant value

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve1.html b/arrayfire/fn.convolve1.html new file mode 100644 index 000000000..962b2b639 --- /dev/null +++ b/arrayfire/fn.convolve1.html @@ -0,0 +1,27 @@ +arrayfire::convolve1 - Rust + + + +

[][src]Function arrayfire::convolve1

pub fn convolve1<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode,
    domain: ConvDomain
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

1d convolution

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be flipped for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes a value of type ConvMode
  • +
  • domain indicates if the convolution should be performed in frequencey or spatial +domain. It takes a value of type ConvDomain
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve2.html b/arrayfire/fn.convolve2.html new file mode 100644 index 000000000..3802cb74b --- /dev/null +++ b/arrayfire/fn.convolve2.html @@ -0,0 +1,27 @@ +arrayfire::convolve2 - Rust + + + +

[][src]Function arrayfire::convolve2

pub fn convolve2<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode,
    domain: ConvDomain
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

2d convolution

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be flipped for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes a value of type ConvMode
  • +
  • domain indicates if the convolution should be performed in frequencey or spatial +domain. It takes a value of type ConvDomain
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve2_gradient_nn.html b/arrayfire/fn.convolve2_gradient_nn.html new file mode 100644 index 000000000..0cef05ef8 --- /dev/null +++ b/arrayfire/fn.convolve2_gradient_nn.html @@ -0,0 +1,29 @@ +arrayfire::convolve2_gradient_nn - Rust + + + +

[][src]Function arrayfire::convolve2_gradient_nn

pub fn convolve2_gradient_nn<T>(
    incoming_grad: &Array<T>,
    original_signal: &Array<T>,
    original_filter: &Array<T>,
    convolved_output: &Array<T>,
    strides: Dim4,
    padding: Dim4,
    dilation: Dim4,
    grad_type: ConvGradientType
) -> Array<T> where
    T: HasAfEnum + RealFloating

Backward pass gradient of 2D convolution

+

Parameters

+
    +
  • incoming_gradient gradients to be distributed in backwards pass
  • +
  • original_signal input signal to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N )
  • +
  • original_filter input filter to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N )
  • +
  • convolved_output output from forward pass of convolution
  • +
  • strides are distance between consecutive elements along each dimension for original convolution
  • +
  • padding specifies padding width along each dimension for original convolution
  • +
  • dilation specifies filter dilation along each dimension for original convolution
  • +
  • grad_type specifies which gradient to return
  • +
+

Return Values

+

Gradient Array w.r.t input generated from convolve2_nn

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve2_nn.html b/arrayfire/fn.convolve2_nn.html new file mode 100644 index 000000000..932c24a1c --- /dev/null +++ b/arrayfire/fn.convolve2_nn.html @@ -0,0 +1,35 @@ +arrayfire::convolve2_nn - Rust + + + +

[][src]Function arrayfire::convolve2_nn

pub fn convolve2_nn<T>(
    signal: &Array<T>,
    filter: &Array<T>,
    strides: Dim4,
    padding: Dim4,
    dilation: Dim4
) -> Array<T> where
    T: HasAfEnum + RealFloating

Convolution Integral for two dimensional data

+

This version of convolution is consistent with the machine learning formulation +that will spatially convolve a filter on 2-dimensions against a signal. Multiple +signals and filters can be batched against each other. Furthermore, the signals +and filters can be multi-dimensional however their dimensions must match. Usually, +this is the forward pass convolution in ML

+

Example:

+

Signals with dimensions: d0 x d1 x d2 x Ns

+

Filters with dimensions: d0 x d1 x d2 x Nf

+

Resulting Convolution: d0 x d1 x Nf x Ns

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is convolution filter
  • +
  • strides are distance between consecutive elements along each dimension for original convolution
  • +
  • padding specifies padding width along each dimension for original convolution
  • +
  • dilation specifies filter dilation along each dimension for original convolution
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve2_sep.html b/arrayfire/fn.convolve2_sep.html new file mode 100644 index 000000000..a283b99a2 --- /dev/null +++ b/arrayfire/fn.convolve2_sep.html @@ -0,0 +1,25 @@ +arrayfire::convolve2_sep - Rust + + + +

[][src]Function arrayfire::convolve2_sep

pub fn convolve2_sep<T, F>(
    cfilt: &Array<F>,
    rfilt: &Array<F>,
    signal: &Array<T>,
    mode: ConvMode
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

Separable convolution for 2d signals

+

Parameters

+
    +
  • cfilt is the filter to be applied along coloumns
  • +
  • rfilt is the filter to be applied along rows
  • +
  • signal is the input signal
  • +
  • mode indicates if the convolution should be expanded or not(where output size equals input)
  • +
+

Return Values

+

The convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.convolve3.html b/arrayfire/fn.convolve3.html new file mode 100644 index 000000000..785e0a1fb --- /dev/null +++ b/arrayfire/fn.convolve3.html @@ -0,0 +1,27 @@ +arrayfire::convolve3 - Rust + + + +

[][src]Function arrayfire::convolve3

pub fn convolve3<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode,
    domain: ConvDomain
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

3d convolution

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be flipped for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes a value of type ConvMode
  • +
  • domain indicates if the convolution should be performed in frequencey or spatial +domain. It takes a value of type ConvDomain
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.corrcoef.html b/arrayfire/fn.corrcoef.html new file mode 100644 index 000000000..7cd28ea12 --- /dev/null +++ b/arrayfire/fn.corrcoef.html @@ -0,0 +1,23 @@ +arrayfire::corrcoef - Rust + + + +

[][src]Function arrayfire::corrcoef

pub fn corrcoef<T>(x: &Array<T>, y: &Array<T>) -> (f64, f64) where
    T: HasAfEnum + RealNumber

Compute correlation coefficient

+

Parameters

+
    +
  • x is the first Array
  • +
  • y isthe second Array
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the coefficients.

+
\ No newline at end of file diff --git a/arrayfire/fn.cos.html b/arrayfire/fn.cos.html new file mode 100644 index 000000000..8587f8b04 --- /dev/null +++ b/arrayfire/fn.cos.html @@ -0,0 +1,17 @@ +arrayfire::cos - Rust + + + +

[][src]Function arrayfire::cos

pub fn cos<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute cos

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.cosh.html b/arrayfire/fn.cosh.html new file mode 100644 index 000000000..cadc40655 --- /dev/null +++ b/arrayfire/fn.cosh.html @@ -0,0 +1,17 @@ +arrayfire::cosh - Rust + + + +

[][src]Function arrayfire::cosh

pub fn cosh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute cosh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.count.html b/arrayfire/fn.count.html new file mode 100644 index 000000000..466fc16b5 --- /dev/null +++ b/arrayfire/fn.count.html @@ -0,0 +1,34 @@ +arrayfire::count - Rust + + + +

[][src]Function arrayfire::count

pub fn count<T>(input: &Array<T>, dim: i32) -> Array<u32> where
    T: HasAfEnum,
    u32: HasAfEnum

Count number of non-zero elements along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the non-zero elements are counted
  • +
+

Return Values

+

Result Array with number of non-zero elements along a given dimension

+

Examples

+
+use arrayfire::{Dim4, gt, print, randu, count};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let cnst: f32 = 0.5;
+let a = gt(&randu::<f32>(dims), &cnst, false);
+print(&a);
+let b = count(&a, 0);
+print(&b);
+let c = count(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.count_all.html b/arrayfire/fn.count_all.html new file mode 100644 index 000000000..d72818b74 --- /dev/null +++ b/arrayfire/fn.count_all.html @@ -0,0 +1,29 @@ +arrayfire::count_all - Rust + + + +

[][src]Function arrayfire::count_all

pub fn count_all<T>(input: &Array<T>) -> (u64, u64) where
    T: HasAfEnum,
    u64: HasAfEnum + Fromf64

Count number of non-zero values in the Array

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the count of non-zero values in the Array.

+

Examples

+
+use arrayfire::{Dim4, print, randu, count_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", count_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.count_by_key.html b/arrayfire/fn.count_by_key.html new file mode 100644 index 000000000..b701ad4e3 --- /dev/null +++ b/arrayfire/fn.count_by_key.html @@ -0,0 +1,24 @@ +arrayfire::count_by_key - Rust + + + +

[][src]Function arrayfire::count_by_key

pub fn count_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Find total count of elements with similar keys along a given dimension

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.cov.html b/arrayfire/fn.cov.html new file mode 100644 index 000000000..f4ca9aed6 --- /dev/null +++ b/arrayfire/fn.cov.html @@ -0,0 +1,25 @@ +arrayfire::cov - Rust + + + +

[][src]Function arrayfire::cov

pub fn cov<T>(
    x: &Array<T>,
    y: &Array<T>,
    isbiased: bool
) -> Array<T::MeanOutType> where
    T: HasAfEnum + CovarianceComputable,
    T::MeanOutType: HasAfEnum
👎 Deprecated since 3.8.0:

Please use cov_v2 API

+

Compute covariance of two Arrays

+

Parameters

+
    +
  • x is the first Array
  • +
  • y is the second Array
  • +
  • isbiased is boolean denoting if biased estimate should be taken(default: False)
  • +
+

Return Values

+

An Array with Covariance values

+
\ No newline at end of file diff --git a/arrayfire/fn.cov_v2.html b/arrayfire/fn.cov_v2.html new file mode 100644 index 000000000..271b16aba --- /dev/null +++ b/arrayfire/fn.cov_v2.html @@ -0,0 +1,24 @@ +arrayfire::cov_v2 - Rust + + + +

[][src]Function arrayfire::cov_v2

pub fn cov_v2<T>(
    x: &Array<T>,
    y: &Array<T>,
    bias_kind: VarianceBias
) -> Array<T::MeanOutType> where
    T: HasAfEnum + CovarianceComputable,
    T::MeanOutType: HasAfEnum

Compute covariance of two Arrays

+

Parameters

+
    +
  • x is the first Array
  • +
  • y is the second Array
  • +
  • bias_kind of type VarianceBias denotes the type of variane to be computed
  • +
+

Return Values

+

An Array with Covariance values

+
\ No newline at end of file diff --git a/arrayfire/fn.cplx.html b/arrayfire/fn.cplx.html new file mode 100644 index 000000000..3bf255ed2 --- /dev/null +++ b/arrayfire/fn.cplx.html @@ -0,0 +1,17 @@ +arrayfire::cplx - Rust + + + +

[][src]Function arrayfire::cplx

pub fn cplx<T: HasAfEnum>(input: &Array<T>) -> Array<T::ComplexOutType> where
    T::ComplexOutType: HasAfEnum

Create a complex Array from real Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.cplx2.html b/arrayfire/fn.cplx2.html new file mode 100644 index 000000000..6114d2b54 --- /dev/null +++ b/arrayfire/fn.cplx2.html @@ -0,0 +1,46 @@ +arrayfire::cplx2 - Rust + + + +

[][src]Function arrayfire::cplx2

pub fn cplx2<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Create complex array from two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.det.html b/arrayfire/fn.det.html new file mode 100644 index 000000000..85476767b --- /dev/null +++ b/arrayfire/fn.det.html @@ -0,0 +1,23 @@ +arrayfire::det - Rust + + + +

[][src]Function arrayfire::det

pub fn det<T>(input: &Array<T>) -> (f64, f64) where
    T: HasAfEnum + FloatingPoint

Find the determinant of the matrix

+

Parameters

+
    +
  • input is the input matrix
  • +
+

Return Values

+

A tuple of 32-bit floating point values.

+

If the input matrix is non-complex type, only first values of tuple contains the result.

+
\ No newline at end of file diff --git a/arrayfire/fn.device_count.html b/arrayfire/fn.device_count.html new file mode 100644 index 000000000..c5af7dfa7 --- /dev/null +++ b/arrayfire/fn.device_count.html @@ -0,0 +1,16 @@ +arrayfire::device_count - Rust + + + +

[][src]Function arrayfire::device_count

pub fn device_count() -> i32

Get total number of available devices

+
\ No newline at end of file diff --git a/arrayfire/fn.device_gc.html b/arrayfire/fn.device_gc.html new file mode 100644 index 000000000..d57dc1cf0 --- /dev/null +++ b/arrayfire/fn.device_gc.html @@ -0,0 +1,16 @@ +arrayfire::device_gc - Rust + + + +

[][src]Function arrayfire::device_gc

pub fn device_gc()

Call the garbage collection routine

+
\ No newline at end of file diff --git a/arrayfire/fn.device_info.html b/arrayfire/fn.device_info.html new file mode 100644 index 000000000..fcd81d468 --- /dev/null +++ b/arrayfire/fn.device_info.html @@ -0,0 +1,18 @@ +arrayfire::device_info - Rust + + + +

[][src]Function arrayfire::device_info

pub fn device_info() -> (String, String, String, String)

Gets the information about device and platform as strings.

+

Return Values

+

A tuple of String indicating the name, platform, toolkit and compute.

+
\ No newline at end of file diff --git a/arrayfire/fn.device_mem_info.html b/arrayfire/fn.device_mem_info.html new file mode 100644 index 000000000..1dfc3da9f --- /dev/null +++ b/arrayfire/fn.device_mem_info.html @@ -0,0 +1,26 @@ +arrayfire::device_mem_info - Rust + + + +

[][src]Function arrayfire::device_mem_info

pub fn device_mem_info() -> (usize, usize, usize, usize)

Get memory information from the memory manager for the current active device

+

Parameters

+

This function doesn't take any input parameters

+

Return Values

+

A quadruple of values regarding the following information.

+
    +
  • Number of bytes allocated
  • +
  • Number of buffers allocated
  • +
  • Number of bytes locked
  • +
  • Number of buffers locked
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.diag_create.html b/arrayfire/fn.diag_create.html new file mode 100644 index 000000000..607b1958d --- /dev/null +++ b/arrayfire/fn.diag_create.html @@ -0,0 +1,24 @@ +arrayfire::diag_create - Rust + + + +

[][src]Function arrayfire::diag_create

pub fn diag_create<T>(input: &Array<T>, dim: i32) -> Array<T> where
    T: HasAfEnum

Create a diagonal matrix

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is the diagonal index relative to principal diagonal where values from input Array are +to be placed
  • +
+

Return Values

+

An Array with values as a diagonal Matrix

+
\ No newline at end of file diff --git a/arrayfire/fn.diag_extract.html b/arrayfire/fn.diag_extract.html new file mode 100644 index 000000000..73b80aace --- /dev/null +++ b/arrayfire/fn.diag_extract.html @@ -0,0 +1,23 @@ +arrayfire::diag_extract - Rust + + + +

[][src]Function arrayfire::diag_extract

pub fn diag_extract<T>(input: &Array<T>, dim: i32) -> Array<T> where
    T: HasAfEnum

Extract diagonal from a given Matrix

+

Parameters

+
    +
  • input is the input Matrix
  • +
  • dim is the index of the diagonal that has to be extracted from the input Matrix
  • +
+

Return Values

+

An Array with values of the diagonal from input Array

+
\ No newline at end of file diff --git a/arrayfire/fn.diff1.html b/arrayfire/fn.diff1.html new file mode 100644 index 000000000..27a0e1fd9 --- /dev/null +++ b/arrayfire/fn.diff1.html @@ -0,0 +1,33 @@ +arrayfire::diff1 - Rust + + + +

[][src]Function arrayfire::diff1

pub fn diff1<T>(input: &Array<T>, dim: i32) -> Array<T::InType> where
    T: HasAfEnum,
    T::InType: HasAfEnum

Calculate first order numerical difference along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which first order difference is calculated
  • +
+

Return Values

+

Result Array with first order difference values

+

Examples

+
+use arrayfire::{Dim4, print, randu, diff1};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = diff1(&a, 0);
+print(&b);
+let c = diff1(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.diff2.html b/arrayfire/fn.diff2.html new file mode 100644 index 000000000..cc4889ddf --- /dev/null +++ b/arrayfire/fn.diff2.html @@ -0,0 +1,33 @@ +arrayfire::diff2 - Rust + + + +

[][src]Function arrayfire::diff2

pub fn diff2<T>(input: &Array<T>, dim: i32) -> Array<T::InType> where
    T: HasAfEnum,
    T::InType: HasAfEnum

Calculate second order numerical difference along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which second order difference is calculated
  • +
+

Return Values

+

Result Array with second order difference values

+

Examples

+
+use arrayfire::{Dim4, print, randu, diff2};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = diff2(&a, 0);
+print(&b);
+let c = diff2(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.dilate.html b/arrayfire/fn.dilate.html new file mode 100644 index 000000000..3af087014 --- /dev/null +++ b/arrayfire/fn.dilate.html @@ -0,0 +1,29 @@ +arrayfire::dilate - Rust + + + +

[][src]Function arrayfire::dilate

pub fn dilate<T>(input: &Array<T>, mask: &Array<T>) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Dilate an Image

+

The dilation function takes two pieces of data as inputs. The first is the input image to be +morphed, and the second is the mask indicating the neighborhood around each pixel to match.

+

In dilation, for each pixel, the mask is centered at the pixel. If the center pixel of the mask +matches the corresponding pixel on the image, then the mask is accepted. If the center pixels +do not matches, then the mask is ignored and no changes are made.

+

For further reference, see here.

+

Parameters

+
    +
  • input is the input image
  • +
  • mask is the morphological operation mask
  • +
+

Return Values

+

Dilated Image(Array)

+
\ No newline at end of file diff --git a/arrayfire/fn.dilate3.html b/arrayfire/fn.dilate3.html new file mode 100644 index 000000000..813831d4a --- /dev/null +++ b/arrayfire/fn.dilate3.html @@ -0,0 +1,25 @@ +arrayfire::dilate3 - Rust + + + +

[][src]Function arrayfire::dilate3

pub fn dilate3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Dilate a Volume

+

Dilation for a volume is similar to the way dilation works on an image. Only difference is that +the masking operation is performed on a volume instead of a rectangular region.

+

Parameters

+
    +
  • input is the input volume
  • +
  • mask is the morphological operation mask
  • +
+

Return Values

+

Dilated Volume(Array)

+
\ No newline at end of file diff --git a/arrayfire/fn.div.html b/arrayfire/fn.div.html new file mode 100644 index 000000000..2b424ae3b --- /dev/null +++ b/arrayfire/fn.div.html @@ -0,0 +1,46 @@ +arrayfire::div - Rust + + + +

[][src]Function arrayfire::div

pub fn div<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Division of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.dog.html b/arrayfire/fn.dog.html new file mode 100644 index 000000000..c95dd4a0c --- /dev/null +++ b/arrayfire/fn.dog.html @@ -0,0 +1,26 @@ +arrayfire::dog - Rust + + + +

[][src]Function arrayfire::dog

pub fn dog<T>(
    input: &Array<T>,
    radius1: i32,
    radius2: i32
) -> Array<T::AbsOutType> where
    T: HasAfEnum + ImageFilterType,
    T::AbsOutType: HasAfEnum

Difference of Gaussians.

+

Given an image, this function computes two different versions of smoothed input image using the +difference smoothing parameters and subtracts one from the other and returns the result.

+

Parameters

+
    +
  • input is the input image
  • +
  • radius1 is the radius of the first gaussian kernel
  • +
  • radius2 is the radius of the second gaussian kernel
  • +
+

Return Values

+

Difference of smoothed inputs - An Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.dot.html b/arrayfire/fn.dot.html new file mode 100644 index 000000000..ad983d247 --- /dev/null +++ b/arrayfire/fn.dot.html @@ -0,0 +1,26 @@ +arrayfire::dot - Rust + + + +

[][src]Function arrayfire::dot

pub fn dot<T>(
    lhs: &Array<T>,
    rhs: &Array<T>,
    optlhs: MatProp,
    optrhs: MatProp
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Calculate the dot product of vectors.

+

Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors.

+

Parameters

+
    +
  • lhs - Left hand side of dot operation
  • +
  • rhs - Right hand side of dot operation
  • +
  • optlhs - Options for lhs. Currently only NONE value from MatProp is supported.
  • +
  • optrhs - Options for rhs. Currently only NONE value from MatProp is supported.
  • +
+

Return Values

+

The result of dot product.

+
\ No newline at end of file diff --git a/arrayfire/fn.eq.html b/arrayfire/fn.eq.html new file mode 100644 index 000000000..9f1a362c8 --- /dev/null +++ b/arrayfire/fn.eq.html @@ -0,0 +1,46 @@ +arrayfire::eq - Rust + + + +

[][src]Function arrayfire::eq

pub fn eq<T, U>(arg1: &T, arg2: &U, batch: bool) -> Array<bool> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Perform equals comparison operation

+

This is a comparison operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the comparison operation a.k.a an Array of boolean values.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.erf.html b/arrayfire/fn.erf.html new file mode 100644 index 000000000..155397b13 --- /dev/null +++ b/arrayfire/fn.erf.html @@ -0,0 +1,17 @@ +arrayfire::erf - Rust + + + +

[][src]Function arrayfire::erf

pub fn erf<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute error function value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.erfc.html b/arrayfire/fn.erfc.html new file mode 100644 index 000000000..52e00c072 --- /dev/null +++ b/arrayfire/fn.erfc.html @@ -0,0 +1,17 @@ +arrayfire::erfc - Rust + + + +

[][src]Function arrayfire::erfc

pub fn erfc<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute the complementary error function value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.erode.html b/arrayfire/fn.erode.html new file mode 100644 index 000000000..b8456c774 --- /dev/null +++ b/arrayfire/fn.erode.html @@ -0,0 +1,30 @@ +arrayfire::erode - Rust + + + +

[][src]Function arrayfire::erode

pub fn erode<T>(input: &Array<T>, mask: &Array<T>) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Erode an Image

+

The erosion function is a morphological transformation on an image that requires two inputs. +The first is the image to be morphed, and the second is the mask indicating neighborhood that +must be white in order to preserve each pixel.

+

In erode, for each pixel, the mask is centered at the pixel. If each pixel of the mask matches +the corresponding pixel on the image, then no change is made. If there is at least one +mismatch, then pixels are changed to the background color (black).

+

For further reference, see here.

+

Parameters

+
    +
  • input is the input image
  • +
  • mask is the morphological operation mask
  • +
+

Return Values

+

Eroded Image(Array)

+
\ No newline at end of file diff --git a/arrayfire/fn.erode3.html b/arrayfire/fn.erode3.html new file mode 100644 index 000000000..a033e7631 --- /dev/null +++ b/arrayfire/fn.erode3.html @@ -0,0 +1,25 @@ +arrayfire::erode3 - Rust + + + +

[][src]Function arrayfire::erode3

pub fn erode3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Erode a Volume

+

Erosion for a volume is similar to the way erosion works on an image. Only difference is that +the masking operation is performed on a volume instead of a rectangular region.

+

Parameters

+
    +
  • input is the input volume
  • +
  • mask is the morphological operation mask
  • +
+

Return Values

+

Eroded Volume(Array)

+
\ No newline at end of file diff --git a/arrayfire/fn.eval_multiple.html b/arrayfire/fn.eval_multiple.html new file mode 100644 index 000000000..850b36468 --- /dev/null +++ b/arrayfire/fn.eval_multiple.html @@ -0,0 +1,21 @@ +arrayfire::eval_multiple - Rust + + + +

[][src]Function arrayfire::eval_multiple

pub fn eval_multiple<T: HasAfEnum>(inputs: Vec<&Array<T>>)

evaluate multiple arrays

+

Use this function to evaluate multiple arrays in single call

+

Parameters

+
    +
  • inputs are the list of arrays to be evaluated
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.exp.html b/arrayfire/fn.exp.html new file mode 100644 index 000000000..57453c644 --- /dev/null +++ b/arrayfire/fn.exp.html @@ -0,0 +1,17 @@ +arrayfire::exp - Rust + + + +

[][src]Function arrayfire::exp

pub fn exp<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute e raised to the power of value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.expm1.html b/arrayfire/fn.expm1.html new file mode 100644 index 000000000..541549542 --- /dev/null +++ b/arrayfire/fn.expm1.html @@ -0,0 +1,17 @@ +arrayfire::expm1 - Rust + + + +

[][src]Function arrayfire::expm1

pub fn expm1<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute e raised to the power of value -1

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.factorial.html b/arrayfire/fn.factorial.html new file mode 100644 index 000000000..aaa963178 --- /dev/null +++ b/arrayfire/fn.factorial.html @@ -0,0 +1,17 @@ +arrayfire::factorial - Rust + + + +

[][src]Function arrayfire::factorial

pub fn factorial<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute the factorial

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.fast.html b/arrayfire/fn.fast.html new file mode 100644 index 000000000..5d2907a50 --- /dev/null +++ b/arrayfire/fn.fast.html @@ -0,0 +1,40 @@ +arrayfire::fast - Rust + + + +

[][src]Function arrayfire::fast

pub fn fast<T>(
    input: &Array<T>,
    thr: f32,
    arc_len: u32,
    non_max: bool,
    feat_ratio: f32,
    edge: u32
) -> Features where
    T: HasAfEnum + ImageFilterType

Fast feature detector

+

A circle of radius 3 pixels, translating into a total of 16 pixels, is checked for sequential +segments of pixels much brighter or much darker than the central one. For a pixel p to be +considered a feature, there must exist a sequential segment of arc_length pixels in the circle +around it such that all are greather than (p + thr) or smaller than (p - thr). After all +features in the image are detected, if nonmax is true, the non-maximal suppression is applied, +checking all detected features and the features detected in its 8-neighborhood and discard it +if its score is non maximal.

+

Parameters

+
    +
  • input - the input image Array
  • +
  • thr - FAST threshold for which pixel of the circle around the center pixel is considered to +be greater or smaller
  • +
  • arc_len - length of arc (or sequential segment) to be tested, must be within range [9-16]
  • +
  • non_max - performs non-maximal supression if true
  • +
  • feat_ratio - maximum ratio of features to detect, the maximum number of features is +calculated by feature_ratio * num of elements. The maximum number of features is not based on +the score, instead, features detected after the limit is reached are discarded.
  • +
  • edge - is the length of the edges in the image to be discarded by FAST(minimum is 3, as the +radius of the circle)
  • +
+

Return Values

+

This function returns an object of struct Features containing Arrays +for x and y coordinates and score, while array oreientation is set to 0 as FAST does not +compute orientation. Size is set to 1 as FAST does not compute multiple scales.

+
\ No newline at end of file diff --git a/arrayfire/fn.fft.html b/arrayfire/fn.fft.html new file mode 100644 index 000000000..73b1f72dc --- /dev/null +++ b/arrayfire/fn.fft.html @@ -0,0 +1,26 @@ +arrayfire::fft - Rust + + + +

[][src]Function arrayfire::fft

pub fn fft<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Fast fourier transform for 1d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signals - used for either truncating or padding the input +signals
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft2.html b/arrayfire/fn.fft2.html new file mode 100644 index 000000000..735fb3c6d --- /dev/null +++ b/arrayfire/fn.fft2.html @@ -0,0 +1,26 @@ +arrayfire::fft2 - Rust + + + +

[][src]Function arrayfire::fft2

pub fn fft2<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64,
    odim1: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Fast fourier transform for 2d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signal first dimension - used for either truncating or padding the input
  • +
  • odim1 is the length of output signal second dimension - used for either truncating or padding the input
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft2_c2r.html b/arrayfire/fn.fft2_c2r.html new file mode 100644 index 000000000..cc147e8b3 --- /dev/null +++ b/arrayfire/fn.fft2_c2r.html @@ -0,0 +1,24 @@ +arrayfire::fft2_c2r - Rust + + + +

[][src]Function arrayfire::fft2_c2r

pub fn fft2_c2r<T>(
    input: &Array<T>,
    norm_factor: f64,
    is_odd: bool
) -> Array<T::BaseType> where
    T: HasAfEnum + ComplexFloating,
    <T as HasAfEnum>::BaseType: HasAfEnum

2d Complex to Real fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • is_odd signifies if the output should be even or odd size
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft2_inplace.html b/arrayfire/fn.fft2_inplace.html new file mode 100644 index 000000000..8d67b2853 --- /dev/null +++ b/arrayfire/fn.fft2_inplace.html @@ -0,0 +1,21 @@ +arrayfire::fft2_inplace - Rust + + + +

[][src]Function arrayfire::fft2_inplace

pub fn fft2_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 2d dimensional Fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.fft2_r2c.html b/arrayfire/fn.fft2_r2c.html new file mode 100644 index 000000000..5e0afdedd --- /dev/null +++ b/arrayfire/fn.fft2_r2c.html @@ -0,0 +1,25 @@ +arrayfire::fft2_r2c - Rust + + + +

[][src]Function arrayfire::fft2_r2c

pub fn fft2_r2c<T>(
    input: &Array<T>,
    norm_factor: f64,
    pad0: i64,
    pad1: i64
) -> Array<Complex<T>> where
    T: HasAfEnum + RealFloating,
    Complex<T>: HasAfEnum

2d Real to Complex fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • pad0 is the padding along 0th dimension of Array
  • +
  • pad1 is the padding along 1st dimension of Array
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft3.html b/arrayfire/fn.fft3.html new file mode 100644 index 000000000..0a78ed326 --- /dev/null +++ b/arrayfire/fn.fft3.html @@ -0,0 +1,27 @@ +arrayfire::fft3 - Rust + + + +

[][src]Function arrayfire::fft3

pub fn fft3<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64,
    odim1: i64,
    odim2: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Fast fourier transform for 3d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signal first dimension - used for either truncating or padding the input
  • +
  • odim1 is the length of output signal second dimension - used for either truncating or padding the input
  • +
  • odim2 is the length of output signal third dimension - used for either truncating or padding the input
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft3_c2r.html b/arrayfire/fn.fft3_c2r.html new file mode 100644 index 000000000..bcf4bcb8e --- /dev/null +++ b/arrayfire/fn.fft3_c2r.html @@ -0,0 +1,24 @@ +arrayfire::fft3_c2r - Rust + + + +

[][src]Function arrayfire::fft3_c2r

pub fn fft3_c2r<T>(
    input: &Array<T>,
    norm_factor: f64,
    is_odd: bool
) -> Array<T::BaseType> where
    T: HasAfEnum + ComplexFloating,
    <T as HasAfEnum>::BaseType: HasAfEnum

3d Complex to Real fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • is_odd signifies if the output should be even or odd size
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft3_inplace.html b/arrayfire/fn.fft3_inplace.html new file mode 100644 index 000000000..1e8480ff9 --- /dev/null +++ b/arrayfire/fn.fft3_inplace.html @@ -0,0 +1,21 @@ +arrayfire::fft3_inplace - Rust + + + +

[][src]Function arrayfire::fft3_inplace

pub fn fft3_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 3d dimensional Fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.fft3_r2c.html b/arrayfire/fn.fft3_r2c.html new file mode 100644 index 000000000..c2e8b9be0 --- /dev/null +++ b/arrayfire/fn.fft3_r2c.html @@ -0,0 +1,26 @@ +arrayfire::fft3_r2c - Rust + + + +

[][src]Function arrayfire::fft3_r2c

pub fn fft3_r2c<T>(
    input: &Array<T>,
    norm_factor: f64,
    pad0: i64,
    pad1: i64,
    pad2: i64
) -> Array<Complex<T>> where
    T: HasAfEnum + RealFloating,
    Complex<T>: HasAfEnum

3d Real to Complex fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • pad0 is the padding along 0th dimension of Array
  • +
  • pad1 is the padding along 1st dimension of Array
  • +
  • pad2 is the padding along 2nd dimension of Array
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft_c2r.html b/arrayfire/fn.fft_c2r.html new file mode 100644 index 000000000..5462a9d13 --- /dev/null +++ b/arrayfire/fn.fft_c2r.html @@ -0,0 +1,24 @@ +arrayfire::fft_c2r - Rust + + + +

[][src]Function arrayfire::fft_c2r

pub fn fft_c2r<T>(
    input: &Array<T>,
    norm_factor: f64,
    is_odd: bool
) -> Array<T::BaseType> where
    T: HasAfEnum + ComplexFloating,
    <T as HasAfEnum>::BaseType: HasAfEnum

1d Complex to Real fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • is_odd signifies if the output should be even or odd size
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft_convolve1.html b/arrayfire/fn.fft_convolve1.html new file mode 100644 index 000000000..377b33ade --- /dev/null +++ b/arrayfire/fn.fft_convolve1.html @@ -0,0 +1,25 @@ +arrayfire::fft_convolve1 - Rust + + + +

[][src]Function arrayfire::fft_convolve1

pub fn fft_convolve1<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

1d convolution using fast-fourier transform

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be used for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes values of type ConvMode
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft_convolve2.html b/arrayfire/fn.fft_convolve2.html new file mode 100644 index 000000000..2f7ead236 --- /dev/null +++ b/arrayfire/fn.fft_convolve2.html @@ -0,0 +1,25 @@ +arrayfire::fft_convolve2 - Rust + + + +

[][src]Function arrayfire::fft_convolve2

pub fn fft_convolve2<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

2d convolution using fast-fourier transform

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be used for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes values of type ConvMode
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft_convolve3.html b/arrayfire/fn.fft_convolve3.html new file mode 100644 index 000000000..23d56f885 --- /dev/null +++ b/arrayfire/fn.fft_convolve3.html @@ -0,0 +1,25 @@ +arrayfire::fft_convolve3 - Rust + + + +

[][src]Function arrayfire::fft_convolve3

pub fn fft_convolve3<T, F>(
    signal: &Array<T>,
    filter: &Array<F>,
    mode: ConvMode
) -> Array<T> where
    T: HasAfEnum,
    F: HasAfEnum

3d convolution using fast-fourier transform

+

Parameters

+
    +
  • signal is the input signal
  • +
  • filter is the signal that shall be used for convolution operation
  • +
  • mode indicates if the convolution should be expanded or not(where output size +equals input). It takes values of type ConvMode
  • +
+

Return Values

+

Convolved Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fft_inplace.html b/arrayfire/fn.fft_inplace.html new file mode 100644 index 000000000..59dfa8f3c --- /dev/null +++ b/arrayfire/fn.fft_inplace.html @@ -0,0 +1,21 @@ +arrayfire::fft_inplace - Rust + + + +

[][src]Function arrayfire::fft_inplace

pub fn fft_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 1d dimensional Fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.fft_r2c.html b/arrayfire/fn.fft_r2c.html new file mode 100644 index 000000000..6d59b545a --- /dev/null +++ b/arrayfire/fn.fft_r2c.html @@ -0,0 +1,24 @@ +arrayfire::fft_r2c - Rust + + + +

[][src]Function arrayfire::fft_r2c

pub fn fft_r2c<T>(
    input: &Array<T>,
    norm_factor: f64,
    pad0: i64
) -> Array<Complex<T>> where
    T: HasAfEnum + RealFloating,
    Complex<T>: HasAfEnum

1d Real to Complex fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor to be applied before fft is applied
  • +
  • pad0 is the padding along 0th dimension of Array
  • +
+

Return Values

+

Complex Array

+
\ No newline at end of file diff --git a/arrayfire/fn.fir.html b/arrayfire/fn.fir.html new file mode 100644 index 000000000..06e846e7a --- /dev/null +++ b/arrayfire/fn.fir.html @@ -0,0 +1,23 @@ +arrayfire::fir - Rust + + + +

[][src]Function arrayfire::fir

pub fn fir<B, X>(b: &Array<B>, x: &Array<X>) -> Array<X> where
    B: HasAfEnum,
    X: HasAfEnum

Finite impulse filter

+

Parameters

+
    +
  • b is the Array containing the coefficients of the filter
  • +
  • x is the input signal to filter
  • +
+

Return Values

+

Filtered Array

+
\ No newline at end of file diff --git a/arrayfire/fn.flat.html b/arrayfire/fn.flat.html new file mode 100644 index 000000000..c8034f172 --- /dev/null +++ b/arrayfire/fn.flat.html @@ -0,0 +1,16 @@ +arrayfire::flat - Rust + + + +

[][src]Function arrayfire::flat

pub fn flat<T>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum

Flatten the multidimensional Array to an 1D Array

+
\ No newline at end of file diff --git a/arrayfire/fn.flip.html b/arrayfire/fn.flip.html new file mode 100644 index 000000000..e166d867d --- /dev/null +++ b/arrayfire/fn.flip.html @@ -0,0 +1,23 @@ +arrayfire::flip - Rust + + + +

[][src]Function arrayfire::flip

pub fn flip<T>(input: &Array<T>, dim: u32) -> Array<T> where
    T: HasAfEnum

Flip the Array

+

Parameters

+
    +
  • input is the Array to be flipped
  • +
  • dim is the dimension along which the flip has to happen
  • +
+

Return Values

+

Flipped Array

+
\ No newline at end of file diff --git a/arrayfire/fn.floor.html b/arrayfire/fn.floor.html new file mode 100644 index 000000000..59b3892df --- /dev/null +++ b/arrayfire/fn.floor.html @@ -0,0 +1,17 @@ +arrayfire::floor - Rust + + + +

[][src]Function arrayfire::floor

pub fn floor<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Floor the values in an Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.free_host.html b/arrayfire/fn.free_host.html new file mode 100644 index 000000000..a763228d8 --- /dev/null +++ b/arrayfire/fn.free_host.html @@ -0,0 +1,16 @@ +arrayfire::free_host - Rust + + + +

[][src]Function arrayfire::free_host

pub fn free_host<T>(ptr: *mut T)

Frees memory allocated by Arrayfire allocator in host memory

+
\ No newline at end of file diff --git a/arrayfire/fn.free_pinned.html b/arrayfire/fn.free_pinned.html new file mode 100644 index 000000000..33d69b8e7 --- /dev/null +++ b/arrayfire/fn.free_pinned.html @@ -0,0 +1,16 @@ +arrayfire::free_pinned - Rust + + + +

[][src]Function arrayfire::free_pinned

pub unsafe fn free_pinned(ptr: void_ptr)

Free the pointer returned by alloc_pinned

+
\ No newline at end of file diff --git a/arrayfire/fn.gaussian_kernel.html b/arrayfire/fn.gaussian_kernel.html new file mode 100644 index 000000000..da2c7d41b --- /dev/null +++ b/arrayfire/fn.gaussian_kernel.html @@ -0,0 +1,32 @@ +arrayfire::gaussian_kernel - Rust + + + +

[][src]Function arrayfire::gaussian_kernel

pub fn gaussian_kernel(
    rows: i32,
    cols: i32,
    sigma_r: f64,
    sigma_c: f64
) -> Array<f32>

Creates a Gaussian Kernel.

+

This function creates a kernel of a specified size that contains a Gaussian distribution. This +distribution is normalized to one. This is most commonly used when performing a Gaussian blur +on an image. The function takes two sets of arguments, the size of the kernel (width and height +in pixels) and the sigma parameters (for row and column) which effect the distribution of the +weights in the y and x directions, respectively.

+

Changing sigma causes the weights in each direction to vary. Sigma is calculated internally as +(0.25 * rows + 0.75) for rows and similarly for columns.

+

Parameters

+
    +
  • rows is number of rows of kernel
  • +
  • cols is number of cols of kernel
  • +
  • sigma_r is standard deviation of rows
  • +
  • sigma_c is standard deviation of cols
  • +
+

Return Values

+

An Array with gaussian kernel values

+
\ No newline at end of file diff --git a/arrayfire/fn.ge.html b/arrayfire/fn.ge.html new file mode 100644 index 000000000..2f40a9faf --- /dev/null +++ b/arrayfire/fn.ge.html @@ -0,0 +1,46 @@ +arrayfire::ge - Rust + + + +

[][src]Function arrayfire::ge

pub fn ge<T, U>(arg1: &T, arg2: &U, batch: bool) -> Array<bool> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Perform greater than equals comparison operation

+

This is a comparison operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the comparison operation a.k.a an Array of boolean values.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.gemm.html b/arrayfire/fn.gemm.html new file mode 100644 index 000000000..f2b0e25c7 --- /dev/null +++ b/arrayfire/fn.gemm.html @@ -0,0 +1,83 @@ +arrayfire::gemm - Rust + + + +

[][src]Function arrayfire::gemm

pub fn gemm<T>(
    output: &mut Array<T>,
    optlhs: MatProp,
    optrhs: MatProp,
    alpha: Vec<T>,
    lhs: &Array<T>,
    rhs: &Array<T>,
    beta: Vec<T>
) where
    T: HasAfEnum + FloatingPoint

BLAS general matrix multiply (GEMM) of two Array objects

+

This provides a general interface to the BLAS level 3 general matrix multiply (GEMM), +which is generally defined as:

+

\begin{equation} +C = \alpha * opA(A)opB(B) + \beta * C +\end{equation}

+

where $\alpha$ (alpha) and $\beta$ (beta) are both scalars; $A$ and $B$ are the matrix +multiply operands; and $opA$ and $opB$ are noop +(if optLhs is MatProp::NONE) or transpose +(if optLhs is MatProp::TRANS) operations on $A$ or $B$ before the +actual GEMM operation. Batched GEMM is supported if at least either $A$ or $B$ have more than +two dimensions (see af::matmul +for more details on broadcasting). However, only one alpha and one beta can be used +for all of the batched matrix operands.

+

The output Array can be used both as an input and output. An allocation will be performed +if you pass an empty Array (i.e. let c: Array<f32> = (0 as i64).into();). If a valid Array +is passed as $C$, the operation will be performed on that Array itself. The C Array must be +the correct type and shape; otherwise, an error will be thrown.

+

Note: Passing an Array that has not been initialized to the C array +will cause undefined behavior.

+

Examples

+

Given below is an example of using gemm API with existing Arrays

+ +
+use arrayfire::{Array, Dim4, print, randu, gemm};
+
+let dims = Dim4::new(&[5, 5, 1, 1]);
+
+let alpha = vec![1.0 as f32];
+let  beta = vec![2.0 as f32];
+
+let lhs = randu::<f32>(dims);
+let rhs = randu::<f32>(dims);
+
+let mut result = Array::new_empty(dims);
+gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE,
+     alpha, &lhs, &rhs, beta);
+

If you don't have an existing Array, you can also use gemm in the following fashion. +However, if there is no existing Array that you need to fill and your use case doesn't +deal with alpha and beta from gemm equation, it is recommended to use +matmul for more terse code.

+ +
+use arrayfire::{Array, Dim4, af_array, print, randu, gemm};
+
+let dims = Dim4::new(&[5, 5, 1, 1]);
+
+let alpha = vec![1.0 as f32];
+let  beta = vec![2.0 as f32];
+
+let lhs = randu::<f32>(dims);
+let rhs = randu::<f32>(dims);
+
+let mut result: Array::<f32> = (std::ptr::null_mut() as af_array).into();
+
+gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE,
+     alpha, &lhs, &rhs, beta);
+

Parameters

+
    +
  • optlhs - Transpose left hand side before the function is performed, uses one of the values of MatProp
  • +
  • optrhs - Transpose right hand side before the function is performed, uses one of the values of MatProp
  • +
  • alpha is alpha value;
  • +
  • lhs is the Array on left hand side
  • +
  • rhs is the Array on right hand side
  • +
  • beta is beta value;
  • +
+

Return Values

+

Array, result of gemm operation

+
\ No newline at end of file diff --git a/arrayfire/fn.get_active_backend.html b/arrayfire/fn.get_active_backend.html new file mode 100644 index 000000000..7964e6a4d --- /dev/null +++ b/arrayfire/fn.get_active_backend.html @@ -0,0 +1,16 @@ +arrayfire::get_active_backend - Rust + + + +

[][src]Function arrayfire::get_active_backend

pub fn get_active_backend() -> Backend

Get current active backend

+
\ No newline at end of file diff --git a/arrayfire/fn.get_available_backends.html b/arrayfire/fn.get_available_backends.html new file mode 100644 index 000000000..ea95dee23 --- /dev/null +++ b/arrayfire/fn.get_available_backends.html @@ -0,0 +1,16 @@ +arrayfire::get_available_backends - Rust + + + +

[][src]Function arrayfire::get_available_backends

pub fn get_available_backends() -> Vec<Backend>

Get the available backends

+
\ No newline at end of file diff --git a/arrayfire/fn.get_backend_count.html b/arrayfire/fn.get_backend_count.html new file mode 100644 index 000000000..4c4e5bbfc --- /dev/null +++ b/arrayfire/fn.get_backend_count.html @@ -0,0 +1,16 @@ +arrayfire::get_backend_count - Rust + + + +

[][src]Function arrayfire::get_backend_count

pub fn get_backend_count() -> u32

Get the available backend count

+
\ No newline at end of file diff --git a/arrayfire/fn.get_default_random_engine.html b/arrayfire/fn.get_default_random_engine.html new file mode 100644 index 000000000..405f4e0b1 --- /dev/null +++ b/arrayfire/fn.get_default_random_engine.html @@ -0,0 +1,16 @@ +arrayfire::get_default_random_engine - Rust + + + +

[][src]Function arrayfire::get_default_random_engine

pub fn get_default_random_engine() -> RandomEngine

Get default random engine

+
\ No newline at end of file diff --git a/arrayfire/fn.get_device.html b/arrayfire/fn.get_device.html new file mode 100644 index 000000000..e0857db72 --- /dev/null +++ b/arrayfire/fn.get_device.html @@ -0,0 +1,16 @@ +arrayfire::get_device - Rust + + + +

[][src]Function arrayfire::get_device

pub fn get_device() -> i32

Get the current active device id

+
\ No newline at end of file diff --git a/arrayfire/fn.get_last_error.html b/arrayfire/fn.get_last_error.html new file mode 100644 index 000000000..a582d1b5e --- /dev/null +++ b/arrayfire/fn.get_last_error.html @@ -0,0 +1,16 @@ +arrayfire::get_last_error - Rust + + + +

[][src]Function arrayfire::get_last_error

pub fn get_last_error() -> String

Fetch last error description as String

+
\ No newline at end of file diff --git a/arrayfire/fn.get_mem_step_size.html b/arrayfire/fn.get_mem_step_size.html new file mode 100644 index 000000000..e53ace589 --- /dev/null +++ b/arrayfire/fn.get_mem_step_size.html @@ -0,0 +1,20 @@ +arrayfire::get_mem_step_size - Rust + + + +

[][src]Function arrayfire::get_mem_step_size

pub fn get_mem_step_size() -> usize

Get the minimum memory chunk size

+

Parameters

+

None

+

Return Values

+

Returns is the size of minimum memory chunk in bytes

+
\ No newline at end of file diff --git a/arrayfire/fn.get_revision.html b/arrayfire/fn.get_revision.html new file mode 100644 index 000000000..3eac01935 --- /dev/null +++ b/arrayfire/fn.get_revision.html @@ -0,0 +1,18 @@ +arrayfire::get_revision - Rust + + + +

[][src]Function arrayfire::get_revision

pub fn get_revision() -> Cow<'static, str>

Get ArrayFire Revision (commit) information of the library.

+

Return Values

+

This returns a Cow<'static, str> as the string is constructed at compile time.

+
\ No newline at end of file diff --git a/arrayfire/fn.get_seed.html b/arrayfire/fn.get_seed.html new file mode 100644 index 000000000..0b1ba7c8c --- /dev/null +++ b/arrayfire/fn.get_seed.html @@ -0,0 +1,16 @@ +arrayfire::get_seed - Rust + + + +

[][src]Function arrayfire::get_seed

pub fn get_seed() -> u64

Get the seed of random number generator

+
\ No newline at end of file diff --git a/arrayfire/fn.get_size.html b/arrayfire/fn.get_size.html new file mode 100644 index 000000000..3d2213115 --- /dev/null +++ b/arrayfire/fn.get_size.html @@ -0,0 +1,16 @@ +arrayfire::get_size - Rust + + + +

[][src]Function arrayfire::get_size

pub fn get_size(value: DType) -> usize

Get size, in bytes, of the arrayfire native type

+
\ No newline at end of file diff --git a/arrayfire/fn.get_version.html b/arrayfire/fn.get_version.html new file mode 100644 index 000000000..e6a72b4a7 --- /dev/null +++ b/arrayfire/fn.get_version.html @@ -0,0 +1,18 @@ +arrayfire::get_version - Rust + + + +

[][src]Function arrayfire::get_version

pub fn get_version() -> (i32, i32, i32)

Get ArrayFire Version Number

+

Return Values

+

A triplet of integers indicating major, minor & fix release version numbers.

+
\ No newline at end of file diff --git a/arrayfire/fn.gradient.html b/arrayfire/fn.gradient.html new file mode 100644 index 000000000..11f5eaaa9 --- /dev/null +++ b/arrayfire/fn.gradient.html @@ -0,0 +1,25 @@ +arrayfire::gradient - Rust + + + +

[][src]Function arrayfire::gradient

pub fn gradient<T>(input: &Array<T>) -> (Array<T>, Array<T>) where
    T: HasAfEnum + FloatingPoint

Calculate the gradients

+

The gradients along the first and second dimensions are calculated simultaneously.

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple of Arrays.

+

The first Array is dx which is the gradient along the 1st dimension.

+

The second Array is dy which is the gradient along the 2nd dimension.

+
\ No newline at end of file diff --git a/arrayfire/fn.gray2rgb.html b/arrayfire/fn.gray2rgb.html new file mode 100644 index 000000000..420fa9430 --- /dev/null +++ b/arrayfire/fn.gray2rgb.html @@ -0,0 +1,24 @@ +arrayfire::gray2rgb - Rust + + + +

[][src]Function arrayfire::gray2rgb

pub fn gray2rgb<T>(input: &Array<T>, r: f32, g: f32, b: f32) -> Array<T> where
    T: HasAfEnum + GrayRGBConvertible

Grayscale to Color(RGB) conversion

+

Parameters

+
    +
  • r is fraction of red channel to appear in output
  • +
  • g is fraction of green channel to appear in output
  • +
  • b is fraction of blue channel to appear in output
  • +
+

#Return Values

+

An Array with image data in target color space

+
\ No newline at end of file diff --git a/arrayfire/fn.gt.html b/arrayfire/fn.gt.html new file mode 100644 index 000000000..5a0bf685f --- /dev/null +++ b/arrayfire/fn.gt.html @@ -0,0 +1,46 @@ +arrayfire::gt - Rust + + + +

[][src]Function arrayfire::gt

pub fn gt<T, U>(arg1: &T, arg2: &U, batch: bool) -> Array<bool> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Perform greater than comparison operation

+

This is a comparison operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the comparison operation a.k.a an Array of boolean values.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.hamming_matcher.html b/arrayfire/fn.hamming_matcher.html new file mode 100644 index 000000000..9d56f3ff7 --- /dev/null +++ b/arrayfire/fn.hamming_matcher.html @@ -0,0 +1,41 @@ +arrayfire::hamming_matcher - Rust + + + +

[][src]Function arrayfire::hamming_matcher

pub fn hamming_matcher<T>(
    query: &Array<T>,
    train: &Array<T>,
    dist_dims: i64,
    n_dist: u32
) -> (Array<u32>, Array<T::AggregateOutType>) where
    T: HasAfEnum + ImageFilterType,
    T::AggregateOutType: HasAfEnum

Hamming feature matcher

+

Calculates Hamming distances between two 2-dimensional arrays containing features, one of the +arrays containing the training data and the other the query data. One of the dimensions of the +both arrays must be equal among them, identifying the length of each feature. The other +dimension indicates the total number of features in each of the training and query arrays. Two +1-dimensional arrays are created as results, one containg the smallest N distances of the query +array and another containing the indices of these distances in the training array. The +resulting 1-dimensional arrays have length equal to the number of features contained in the +query array.

+

Parameters

+
    +
  • query - Array containing the data to be queried
  • +
  • train - Array containing the data to be used as training data
  • +
  • dist_dims - indicates the dimension to analyze for distance (the dimension indicated here +must be of equal length for both query and train arrays)
  • +
  • n_dist - is the number of smallest distances to return (currently, only values <= 256 are supported)
  • +
+

Return Values

+

This function returns a tuple of Array's.

+

First Array is an array of MxN size, where M is equal to the number of query features and N is +equal to n_dist. The value at position IxJ indicates the index of the Jth smallest distance to +the Ith query value in the train data array. the index of the Ith smallest distance of the Mth +query.

+

Second Array is an array of MxN size, where M is equal to the number of query features and N is +equal to n_dist. The value at position IxJ indicates the Hamming distance of the Jth smallest +distance to the Ith query value in the train data array.

+
\ No newline at end of file diff --git a/arrayfire/fn.handle_error_general.html b/arrayfire/fn.handle_error_general.html new file mode 100644 index 000000000..f0d207c09 --- /dev/null +++ b/arrayfire/fn.handle_error_general.html @@ -0,0 +1,16 @@ +arrayfire::handle_error_general - Rust + + + +

[][src]Function arrayfire::handle_error_general

pub fn handle_error_general(error_code: AfError)

Default error handling callback provided by ArrayFire crate

+
\ No newline at end of file diff --git a/arrayfire/fn.harris.html b/arrayfire/fn.harris.html new file mode 100644 index 000000000..7f2730cb5 --- /dev/null +++ b/arrayfire/fn.harris.html @@ -0,0 +1,33 @@ +arrayfire::harris - Rust + + + +

[][src]Function arrayfire::harris

pub fn harris<T>(
    input: &Array<T>,
    max_corners: u32,
    min_response: f32,
    sigma: f32,
    block_size: u32,
    k_thr: f32
) -> Features where
    T: HasAfEnum + RealFloating

Harris corner detector.

+

Compute corners using the Harris corner detector approach. For each pixel, a small window is +used to calculate the determinant and trace of such a window, from which a response is +calculated. Pixels are considered corners if they are local maximas and have a high positive +response.

+

Parameters

+
    +
  • input is the array containing a grayscale image (color images are not supported)
  • +
  • max_corners is the maximum number of corners to keep, only retains those with highest Harris responses
  • +
  • min_response is the minimum response in order for a corner to be retained, only used if max_corners = 0
  • +
  • sigma is the standard deviation of a circular window (its dimensions will be calculated according to the standard deviation), the covariation matrix will be calculated to a circular neighborhood of this standard deviation (only used when block_size == 0, must be >= 0.5f and <= 5.0f)
  • +
  • block_size is square window size, the covariation matrix will be calculated to a square neighborhood of this size (must be >= 3 and <= 31)
  • +
  • k_thr is the Harris constant, usually set empirically to 0.04f (must be >= 0.01f)
  • +
+

Return Values

+

This function returns an object of struct Features containing Arrays +for x and y coordinates and score, while array oreientation & size are set to 0 & 1, +respectively, since harris doesn't compute that information

+
\ No newline at end of file diff --git a/arrayfire/fn.hist_equal.html b/arrayfire/fn.hist_equal.html new file mode 100644 index 000000000..d4a4bdfa0 --- /dev/null +++ b/arrayfire/fn.hist_equal.html @@ -0,0 +1,23 @@ +arrayfire::hist_equal - Rust + + + +

[][src]Function arrayfire::hist_equal

pub fn hist_equal<T>(input: &Array<T>, hist: &Array<u32>) -> Array<T> where
    T: HasAfEnum + RealNumber

Histogram Equalization

+

Parameters

+
    +
  • input is the input Array to be equalized
  • +
  • hist is the Array to be used for equalizing input
  • +
+

Return Values

+

Equalized Array

+
\ No newline at end of file diff --git a/arrayfire/fn.histogram.html b/arrayfire/fn.histogram.html new file mode 100644 index 000000000..ac3afbcfe --- /dev/null +++ b/arrayfire/fn.histogram.html @@ -0,0 +1,34 @@ +arrayfire::histogram - Rust + + + +

[][src]Function arrayfire::histogram

pub fn histogram<T>(
    input: &Array<T>,
    nbins: u32,
    minval: f64,
    maxval: f64
) -> Array<u32> where
    T: HasAfEnum + RealNumber

Compute Histogram of an Array

+

A histogram is a representation of the distribution of given data. This representation is +essentially a graph consisting of the data range or domain on one axis and frequency of +occurence on the other axis. All the data in the domain is counted in the appropriate bin. The +total number of elements belonging to each bin is known as the bin's frequency.

+

The regular histogram function creates bins of equal size between the minimum and maximum of +the input data (min and max are calculated internally). The histogram min-max function takes +input parameters minimum and maximum, and divides the bins into equal sizes within the range +specified by min and max parameters. All values less than min in the data range are placed in +the first (min) bin and all values greater than max will be placed in the last (max) bin.

+

Parameters

+
    +
  • input is the Array whose histogram has to be computed
  • +
  • nbins is the number bins the input data has to be categorized into.
  • +
  • minval is the minimum value of bin ordering
  • +
  • maxval is the maximum value of bin ordering
  • +
+

Return Values

+

Histogram of input Array

+
\ No newline at end of file diff --git a/arrayfire/fn.homography.html b/arrayfire/fn.homography.html new file mode 100644 index 000000000..5eadf8cb2 --- /dev/null +++ b/arrayfire/fn.homography.html @@ -0,0 +1,44 @@ +arrayfire::homography - Rust + + + +

[][src]Function arrayfire::homography

pub fn homography<OutType>(
    x_src: &Array<f32>,
    y_src: &Array<f32>,
    x_dst: &Array<f32>,
    y_dst: &Array<f32>,
    htype: HomographyType,
    inlier_thr: f32,
    iterations: u32
) -> (Array<OutType>, i32) where
    OutType: HasAfEnum + RealFloating

Homography estimation

+

Homography estimation find a perspective transform between two sets of 2D points. +Currently, two methods are supported for the estimation, RANSAC (RANdom SAmple Consensus) +and LMedS (Least Median of Squares). Both methods work by randomly selecting a subset +of 4 points of the set of source points, computing the eigenvectors of that set and +finding the perspective transform. The process is repeated several times, a maximum of +times given by the value passed to the iterations arguments for RANSAC (for the CPU +backend, usually less than that, depending on the quality of the dataset, but for CUDA +and OpenCL backends the transformation will be computed exactly the amount of times +passed via the iterations parameter), the returned value is the one that matches the +best number of inliers, which are all of the points that fall within a maximum L2 +distance from the value passed to the inlier_thr argument.

+

Parameters

+
    +
  • x_src is the x coordinates of the source points.
  • +
  • y_src is the y coordinates of the source points.
  • +
  • x_dst is the x coordinates of the destination points.
  • +
  • y_dst is the y coordinates of the destination points.
  • +
  • htype can be AF_HOMOGRAPHY_RANSAC, for which a RANdom SAmple Consensus will be used to evaluate the homography quality (e.g., number of inliers), or AF_HOMOGRAPHY_LMEDS, which will use Least Median of Squares method to evaluate homography quality
  • +
  • inlier_thr - if htype is AF_HOMOGRAPHY_RANSAC, this parameter will five the maximum L2-distance for a point to be considered an inlier.
  • +
  • iterations is the maximum number of iterations when htype is AF_HOMOGRAPHY_RANSAC and backend is CPU,if backend is CUDA or OpenCL, iterations is the total number of iterations, an iteration is a selection of 4 random points for which the homography is estimated and evaluated for number of inliers.
  • +
  • otype is the array type for the homography output.
  • +
+

Return Values

+

Returns a tuple of Array and int.

+
    +
  • H is a 3x3 array containing the estimated homography.
  • +
  • inliers is the number of inliers that the homography was estimated to comprise, in the case that htype is AF_HOMOGRAPHY_RANSAC, a higher inlier_thr value will increase the estimated inliers. Note that if the number of inliers is too low, it is likely that a bad homography will be returned.
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.hsv2rgb.html b/arrayfire/fn.hsv2rgb.html new file mode 100644 index 000000000..3813f18f2 --- /dev/null +++ b/arrayfire/fn.hsv2rgb.html @@ -0,0 +1,16 @@ +arrayfire::hsv2rgb - Rust + + + +

[][src]Function arrayfire::hsv2rgb

pub fn hsv2rgb<T>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum + RealFloating

HSV to RGB color space conversion

+
\ No newline at end of file diff --git a/arrayfire/fn.hypot.html b/arrayfire/fn.hypot.html new file mode 100644 index 000000000..53fd8911c --- /dev/null +++ b/arrayfire/fn.hypot.html @@ -0,0 +1,33 @@ +arrayfire::hypot - Rust + + + +

[][src]Function arrayfire::hypot

pub fn hypot<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Compute length of hypotenuse of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.identity.html b/arrayfire/fn.identity.html new file mode 100644 index 000000000..9eeb83424 --- /dev/null +++ b/arrayfire/fn.identity.html @@ -0,0 +1,22 @@ +arrayfire::identity - Rust + + + +

[][src]Function arrayfire::identity

pub fn identity<T: HasAfEnum>(dims: Dim4) -> Array<T>

Create an identity array with 1's in diagonal

+

Parameters

+
    +
  • dims is the output Array dimensions
  • +
+

Return Values

+

Identity matrix

+
\ No newline at end of file diff --git a/arrayfire/fn.ifft.html b/arrayfire/fn.ifft.html new file mode 100644 index 000000000..59ad32cc9 --- /dev/null +++ b/arrayfire/fn.ifft.html @@ -0,0 +1,26 @@ +arrayfire::ifft - Rust + + + +

[][src]Function arrayfire::ifft

pub fn ifft<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Inverse fast fourier transform for 1d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signals - used for either truncating or padding the input +signals
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.ifft2.html b/arrayfire/fn.ifft2.html new file mode 100644 index 000000000..aecf0dd87 --- /dev/null +++ b/arrayfire/fn.ifft2.html @@ -0,0 +1,26 @@ +arrayfire::ifft2 - Rust + + + +

[][src]Function arrayfire::ifft2

pub fn ifft2<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64,
    odim1: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Inverse fast fourier transform for 2d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signal first dimension - used for either truncating or padding the input
  • +
  • odim1 is the length of output signal second dimension - used for either truncating or padding the input
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.ifft2_inplace.html b/arrayfire/fn.ifft2_inplace.html new file mode 100644 index 000000000..8fc70217b --- /dev/null +++ b/arrayfire/fn.ifft2_inplace.html @@ -0,0 +1,21 @@ +arrayfire::ifft2_inplace - Rust + + + +

[][src]Function arrayfire::ifft2_inplace

pub fn ifft2_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 2d dimensional inverse fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.ifft3.html b/arrayfire/fn.ifft3.html new file mode 100644 index 000000000..8b96804f5 --- /dev/null +++ b/arrayfire/fn.ifft3.html @@ -0,0 +1,27 @@ +arrayfire::ifft3 - Rust + + + +

[][src]Function arrayfire::ifft3

pub fn ifft3<T>(
    input: &Array<T>,
    norm_factor: f64,
    odim0: i64,
    odim1: i64,
    odim2: i64
) -> Array<T::ComplexOutType> where
    T: HasAfEnum + FloatingPoint,
    <T as HasAfEnum>::ComplexOutType: HasAfEnum

Inverse fast fourier transform for 3d signals

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor with which the input is scaled before the +transformation is applied
  • +
  • odim0 is the length of output signal first dimension - used for either truncating or padding the input
  • +
  • odim1 is the length of output signal second dimension - used for either truncating or padding the input
  • +
  • odim2 is the length of output signal third dimension - used for either truncating or padding the input
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.ifft3_inplace.html b/arrayfire/fn.ifft3_inplace.html new file mode 100644 index 000000000..69ba9ab0b --- /dev/null +++ b/arrayfire/fn.ifft3_inplace.html @@ -0,0 +1,21 @@ +arrayfire::ifft3_inplace - Rust + + + +

[][src]Function arrayfire::ifft3_inplace

pub fn ifft3_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 3d dimensional inverse fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.ifft_inplace.html b/arrayfire/fn.ifft_inplace.html new file mode 100644 index 000000000..d6dfd4aca --- /dev/null +++ b/arrayfire/fn.ifft_inplace.html @@ -0,0 +1,21 @@ +arrayfire::ifft_inplace - Rust + + + +

[][src]Function arrayfire::ifft_inplace

pub fn ifft_inplace<T>(input: &mut Array<T>, norm_factor: f64) where
    T: HasAfEnum + ComplexFloating

In place 1d dimensional inverse fast fourier transform

+

Parameters

+
    +
  • input is the input Array
  • +
  • norm_factor is the normalization factor
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.iir.html b/arrayfire/fn.iir.html new file mode 100644 index 000000000..55603d394 --- /dev/null +++ b/arrayfire/fn.iir.html @@ -0,0 +1,24 @@ +arrayfire::iir - Rust + + + +

[][src]Function arrayfire::iir

pub fn iir<T: HasAfEnum>(b: &Array<T>, a: &Array<T>, x: &Array<T>) -> Array<T>

Infinite impulse response filter

+

Parameters

+
    +
  • b is the Array containing the feedforward coefficients
  • +
  • a is the Array containing the feedback coefficients
  • +
  • x is the input signal to filter
  • +
+

Return Values

+

Filtered Array

+
\ No newline at end of file diff --git a/arrayfire/fn.imag.html b/arrayfire/fn.imag.html new file mode 100644 index 000000000..5887fd3c1 --- /dev/null +++ b/arrayfire/fn.imag.html @@ -0,0 +1,17 @@ +arrayfire::imag - Rust + + + +

[][src]Function arrayfire::imag

pub fn imag<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Extract imaginary values from a complex Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.imax.html b/arrayfire/fn.imax.html new file mode 100644 index 000000000..9bbf85df6 --- /dev/null +++ b/arrayfire/fn.imax.html @@ -0,0 +1,23 @@ +arrayfire::imax - Rust + + + +

[][src]Function arrayfire::imax

pub fn imax<T>(input: &Array<T>, dim: i32) -> (Array<T::InType>, Array<u32>) where
    T: HasAfEnum,
    T::InType: HasAfEnum

Find maximum value along given dimension and their corresponding indices

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

A tuple of Arrays: Array maximum values and Array containing their index along the reduced dimension.

+
\ No newline at end of file diff --git a/arrayfire/fn.imax_all.html b/arrayfire/fn.imax_all.html new file mode 100644 index 000000000..797687e37 --- /dev/null +++ b/arrayfire/fn.imax_all.html @@ -0,0 +1,25 @@ +arrayfire::imax_all - Rust + + + +

[][src]Function arrayfire::imax_all

pub fn imax_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::InType as HasAfEnum>::BaseType, <<T as HasAfEnum>::InType as HasAfEnum>::BaseType, u32) where
    T: HasAfEnum,
    <T as HasAfEnum>::InType: HasAfEnum,
    <<T as HasAfEnum>::InType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Find maximum and it's index in the whole Array

+

Parameters

+

input - Input Array

+

Return Values

+

A triplet with

+
    +
  • maximum element of Array in the first component.
  • +
  • second component of value zero if Array is of non-complex type.
  • +
  • index of maximum element in the third component.
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.imin.html b/arrayfire/fn.imin.html new file mode 100644 index 000000000..3bc8e03b3 --- /dev/null +++ b/arrayfire/fn.imin.html @@ -0,0 +1,23 @@ +arrayfire::imin - Rust + + + +

[][src]Function arrayfire::imin

pub fn imin<T>(input: &Array<T>, dim: i32) -> (Array<T::InType>, Array<u32>) where
    T: HasAfEnum,
    T::InType: HasAfEnum

Find minimum value along given dimension and their corresponding indices

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

A tuple of Arrays: Array minimum values and Array containing their index along the reduced dimension.

+
\ No newline at end of file diff --git a/arrayfire/fn.imin_all.html b/arrayfire/fn.imin_all.html new file mode 100644 index 000000000..fb2629b01 --- /dev/null +++ b/arrayfire/fn.imin_all.html @@ -0,0 +1,25 @@ +arrayfire::imin_all - Rust + + + +

[][src]Function arrayfire::imin_all

pub fn imin_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::InType as HasAfEnum>::BaseType, <<T as HasAfEnum>::InType as HasAfEnum>::BaseType, u32) where
    T: HasAfEnum,
    <T as HasAfEnum>::InType: HasAfEnum,
    <<T as HasAfEnum>::InType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Find minimum and it's index in the whole Array

+

Parameters

+

input - Input Array

+

Return Values

+

A triplet with

+
    +
  • minimum element of Array in the first component.
  • +
  • second component of value zero if Array is of non-complex type.
  • +
  • index of minimum element in the third component.
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.index.html b/arrayfire/fn.index.html new file mode 100644 index 000000000..a9584ac11 --- /dev/null +++ b/arrayfire/fn.index.html @@ -0,0 +1,25 @@ +arrayfire::index - Rust + + + +

[][src]Function arrayfire::index

pub fn index<IO, T>(input: &Array<IO>, seqs: &[Seq<T>]) -> Array<IO> where
    c_double: From<T>,
    IO: HasAfEnum,
    T: Copy + HasAfEnum + IndexableType

Indexes the input Array using seqs Sequences

+

Examples

+
+use arrayfire::{Dim4, Seq, index, randu, print};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
+let sub  = index(&a, seqs);
+println!("a(seq(1, 3, 1), span)");
+print(&sub);
+
\ No newline at end of file diff --git a/arrayfire/fn.index_gen.html b/arrayfire/fn.index_gen.html new file mode 100644 index 000000000..8d9a843fb --- /dev/null +++ b/arrayfire/fn.index_gen.html @@ -0,0 +1,41 @@ +arrayfire::index_gen - Rust + + + +

[][src]Function arrayfire::index_gen

pub fn index_gen<T>(input: &Array<T>, indices: Indexer<'_>) -> Array<T> where
    T: HasAfEnum

Index an Array using any combination of Array's and Sequence's

+

Examples

+
+use arrayfire::{Array, Dim4, Seq, print, randu, index_gen, Indexer};
+let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+let seq4gen = Seq::new(0.0, 2.0, 1.0);
+let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+// [5 3 1 1]
+//     0.0000     0.2190     0.3835
+//     0.1315     0.0470     0.5194
+//     0.7556     0.6789     0.8310
+//     0.4587     0.6793     0.0346
+//     0.5328     0.9347     0.0535
+
+
+let mut idxrs = Indexer::default();
+idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
+idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
+
+let sub2 = index_gen(&a, idxrs);
+println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+// [3 3 1 1]
+//     0.1315     0.0470     0.5194
+//     0.7556     0.6789     0.8310
+//     0.4587     0.6793     0.0346
+
\ No newline at end of file diff --git a/arrayfire/fn.info.html b/arrayfire/fn.info.html new file mode 100644 index 000000000..8cbda0d72 --- /dev/null +++ b/arrayfire/fn.info.html @@ -0,0 +1,22 @@ +arrayfire::info - Rust + + + +

[][src]Function arrayfire::info

pub fn info()

Print library meta-info

+

Examples

+

An example output of af::info call looks like below

+
ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38)
+Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000
+[0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0
+
+
\ No newline at end of file diff --git a/arrayfire/fn.info_string.html b/arrayfire/fn.info_string.html new file mode 100644 index 000000000..ff006822f --- /dev/null +++ b/arrayfire/fn.info_string.html @@ -0,0 +1,22 @@ +arrayfire::info_string - Rust + + + +

[][src]Function arrayfire::info_string

pub fn info_string(verbose: bool) -> String

Return library meta-info as String

+

Examples

+

An example output of af::info_string call looks like below

+
ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38)
+Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000
+[0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0
+
+
\ No newline at end of file diff --git a/arrayfire/fn.init.html b/arrayfire/fn.init.html new file mode 100644 index 000000000..27f758fde --- /dev/null +++ b/arrayfire/fn.init.html @@ -0,0 +1,18 @@ +arrayfire::init - Rust + + + +

[][src]Function arrayfire::init

pub fn init()

Initialize ArrayFire library

+

0th device will be the default device unless init call +is followed by set_device

+
\ No newline at end of file diff --git a/arrayfire/fn.inverse.html b/arrayfire/fn.inverse.html new file mode 100644 index 000000000..35366703e --- /dev/null +++ b/arrayfire/fn.inverse.html @@ -0,0 +1,24 @@ +arrayfire::inverse - Rust + + + +

[][src]Function arrayfire::inverse

pub fn inverse<T>(input: &Array<T>, options: MatProp) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Compute inverse of a matrix

+

Parameters

+
    +
  • input is the input matrix
  • +
  • options determine various properties of input matrix
  • +
+

The parameter options currently take only the value NONE.

+

Return Values

+

An Array with values of the inverse of input matrix.

+
\ No newline at end of file diff --git a/arrayfire/fn.inverse_deconv.html b/arrayfire/fn.inverse_deconv.html new file mode 100644 index 000000000..954365f7a --- /dev/null +++ b/arrayfire/fn.inverse_deconv.html @@ -0,0 +1,37 @@ +arrayfire::inverse_deconv - Rust + + + +

[][src]Function arrayfire::inverse_deconv

pub fn inverse_deconv<T>(
    input: &Array<T>,
    kernel: &Array<f32>,
    gamma: f32,
    algo: InverseDeconvAlgo
) -> Array<T::AbsOutType> where
    T: DeconvInput,
    T::AbsOutType: HasAfEnum

Inverse deconvolution

+

This is a linear algorithm i.e. they are non-iterative in +nature and usually faster than iterative deconvolution algorithms.

+

Depending on the values passed on to algo of type enum InverseDeconvAlgo, +different equations are used to compute the final result.

+

Tikhonov's Deconvolution Method:

+

The update equation for this algorithm is as follows:

+
+\begin{equation} +\hat{I}_{\omega} = \frac{ I_{\omega} * P^{*}_{\omega} } { |P_{\omega}|^2 + \gamma } +\end{equation} +
+

where

+
    +
  • $ I_{\omega} $ is the observed(input/blurred) image in frequency domain
  • +
  • $ P_{\omega} $ is the point spread function in frequency domain
  • +
  • $ \gamma $ is a user defined regularization constant
  • +
+

The type of output Array from deconvolution will be double if the input array type is double. +Otherwise, it will be float in rest of the cases. Should the caller want to save the image to +disk or require the values of output to be in a fixed range, that should be done by the caller +explicitly.

+
\ No newline at end of file diff --git a/arrayfire/fn.iota.html b/arrayfire/fn.iota.html new file mode 100644 index 000000000..637e116e8 --- /dev/null +++ b/arrayfire/fn.iota.html @@ -0,0 +1,24 @@ +arrayfire::iota - Rust + + + +

[][src]Function arrayfire::iota

pub fn iota<T: HasAfEnum>(dims: Dim4, tdims: Dim4) -> Array<T>

Create a range of values

+

Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims.

+

Parameters

+
    +
  • dims is the dimensions of the sequence to be generated
  • +
  • tdims is the number of repitions of the unit dimensions
  • +
+

Return Values

+

Array

+
\ No newline at end of file diff --git a/arrayfire/fn.is_double_available.html b/arrayfire/fn.is_double_available.html new file mode 100644 index 000000000..83e40a3d6 --- /dev/null +++ b/arrayfire/fn.is_double_available.html @@ -0,0 +1,22 @@ +arrayfire::is_double_available - Rust + + + +

[][src]Function arrayfire::is_double_available

pub fn is_double_available(device: i32) -> bool

Check if a device has double support

+

Parameters

+
    +
  • device is the device for which double support is checked for
  • +
+

Return Values

+

True if device device has double support, False otherwise.

+
\ No newline at end of file diff --git a/arrayfire/fn.is_eval_manual.html b/arrayfire/fn.is_eval_manual.html new file mode 100644 index 000000000..3e8ff63d1 --- /dev/null +++ b/arrayfire/fn.is_eval_manual.html @@ -0,0 +1,20 @@ +arrayfire::is_eval_manual - Rust + + + +

[][src]Function arrayfire::is_eval_manual

pub fn is_eval_manual() -> bool

Get eval flag value

+

This function can be used to find out if manual evaluation of arrays is +turned on or off.

+

Return Values

+

A boolean indicating manual evaluation setting.

+
\ No newline at end of file diff --git a/arrayfire/fn.is_half_available.html b/arrayfire/fn.is_half_available.html new file mode 100644 index 000000000..8b02c7920 --- /dev/null +++ b/arrayfire/fn.is_half_available.html @@ -0,0 +1,22 @@ +arrayfire::is_half_available - Rust + + + +

[][src]Function arrayfire::is_half_available

pub fn is_half_available(device: i32) -> bool

Check if a device has half support

+

Parameters

+
    +
  • device is the device for which half precision support is checked for
  • +
+

Return Values

+

True if device device has half support, False otherwise.

+
\ No newline at end of file diff --git a/arrayfire/fn.is_imageio_available.html b/arrayfire/fn.is_imageio_available.html new file mode 100644 index 000000000..32a1c952f --- /dev/null +++ b/arrayfire/fn.is_imageio_available.html @@ -0,0 +1,20 @@ +arrayfire::is_imageio_available - Rust + + + +

[][src]Function arrayfire::is_imageio_available

pub fn is_imageio_available() -> bool

Function to check if Image I/O is available

+

Parameters

+

None

+

Return Values

+

Return a boolean indicating if ArrayFire was compiled with Image I/O support

+
\ No newline at end of file diff --git a/arrayfire/fn.is_lapack_available.html b/arrayfire/fn.is_lapack_available.html new file mode 100644 index 000000000..c5ba1f8d6 --- /dev/null +++ b/arrayfire/fn.is_lapack_available.html @@ -0,0 +1,20 @@ +arrayfire::is_lapack_available - Rust + + + +

[][src]Function arrayfire::is_lapack_available

pub fn is_lapack_available() -> bool

Function to check if lapack support is available

+

Parameters

+

None

+

Return Values

+

Return a boolean indicating if ArrayFire was compiled with lapack support

+
\ No newline at end of file diff --git a/arrayfire/fn.isinf.html b/arrayfire/fn.isinf.html new file mode 100644 index 000000000..0380b54a5 --- /dev/null +++ b/arrayfire/fn.isinf.html @@ -0,0 +1,17 @@ +arrayfire::isinf - Rust + + + +

[][src]Function arrayfire::isinf

pub fn isinf<T: HasAfEnum>(input: &Array<T>) -> Array<bool>

Check if values are infinity

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.isnan.html b/arrayfire/fn.isnan.html new file mode 100644 index 000000000..9becea5e6 --- /dev/null +++ b/arrayfire/fn.isnan.html @@ -0,0 +1,17 @@ +arrayfire::isnan - Rust + + + +

[][src]Function arrayfire::isnan

pub fn isnan<T: HasAfEnum>(input: &Array<T>) -> Array<bool>

Check if values are NaN

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.iszero.html b/arrayfire/fn.iszero.html new file mode 100644 index 000000000..6a7f96232 --- /dev/null +++ b/arrayfire/fn.iszero.html @@ -0,0 +1,17 @@ +arrayfire::iszero - Rust + + + +

[][src]Function arrayfire::iszero

pub fn iszero<T: HasAfEnum>(input: &Array<T>) -> Array<bool>

Check if values are zero

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.iterative_deconv.html b/arrayfire/fn.iterative_deconv.html new file mode 100644 index 000000000..4025bee9b --- /dev/null +++ b/arrayfire/fn.iterative_deconv.html @@ -0,0 +1,47 @@ +arrayfire::iterative_deconv - Rust + + + +

[][src]Function arrayfire::iterative_deconv

pub fn iterative_deconv<T>(
    input: &Array<T>,
    kernel: &Array<f32>,
    iterations: u32,
    relaxation_factor: f32,
    algo: IterativeDeconvAlgo
) -> Array<T::AbsOutType> where
    T: DeconvInput,
    T::AbsOutType: HasAfEnum

Iterative Deconvolution

+

The following table shows the iteration update equations of the respective +deconvolution algorithms.

+ + + + + + + + + + +
AlgorithmUpdate Equation
LandWeber + $ \hat{I}_{n} = \hat{I}_{n-1} + \alpha * P^T \otimes (I - P \otimes \hat{I}_{n-1}) $ +
Richardson-Lucy + $ \hat{I}_{n} = \hat{I}_{n-1} . ( \frac{I}{\hat{I}_{n-1} \otimes P} \otimes P^T ) $ +
+

where

+
    +
  • $ I $ is the observed(input/blurred) image
  • +
  • $ P $ is the point spread function
  • +
  • $ P^T $ is the transpose of point spread function
  • +
  • $ \hat{I}_{n} $ is the current iteration's updated image estimate
  • +
  • $ \hat{I}_{n-1} $ is the previous iteration's image estimate
  • +
  • $ \alpha $ is the relaxation factor
  • +
  • $ \otimes $ indicates the convolution operator
  • +
+

The type of output Array from deconvolution will be of type f64 if +the input array type is f64. For other types, output type will be f32 type. +Should the caller want to save the image to disk or require the values of output +to be in a fixed range, that should be done by the caller explicitly.

+
\ No newline at end of file diff --git a/arrayfire/fn.join.html b/arrayfire/fn.join.html new file mode 100644 index 000000000..5937e7a95 --- /dev/null +++ b/arrayfire/fn.join.html @@ -0,0 +1,24 @@ +arrayfire::join - Rust + + + +

[][src]Function arrayfire::join

pub fn join<T>(dim: i32, first: &Array<T>, second: &Array<T>) -> Array<T> where
    T: HasAfEnum

Join two arrays

+

Parameters

+
    +
  • dim is the dimension along which the concatenation has to be done
  • +
  • first is the Array that comes first in the concatenation
  • +
  • second is the Array that comes last in the concatenation
  • +
+

Return Values

+

Concatenated Array

+
\ No newline at end of file diff --git a/arrayfire/fn.join_many.html b/arrayfire/fn.join_many.html new file mode 100644 index 000000000..40c81e58f --- /dev/null +++ b/arrayfire/fn.join_many.html @@ -0,0 +1,23 @@ +arrayfire::join_many - Rust + + + +

[][src]Function arrayfire::join_many

pub fn join_many<T>(dim: i32, inputs: Vec<&Array<T>>) -> Array<T> where
    T: HasAfEnum

Join multiple arrays

+

Parameters

+
    +
  • dim is the dimension along which the concatenation has to be done
  • +
  • inputs is the vector of Arrays that has to be concatenated
  • +
+

Return Values

+

Concatenated Array

+
\ No newline at end of file diff --git a/arrayfire/fn.le.html b/arrayfire/fn.le.html new file mode 100644 index 000000000..02978ca34 --- /dev/null +++ b/arrayfire/fn.le.html @@ -0,0 +1,46 @@ +arrayfire::le - Rust + + + +

[][src]Function arrayfire::le

pub fn le<T, U>(arg1: &T, arg2: &U, batch: bool) -> Array<bool> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Perform less than equals comparison operation

+

This is a comparison operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the comparison operation a.k.a an Array of boolean values.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.lgamma.html b/arrayfire/fn.lgamma.html new file mode 100644 index 000000000..796cca579 --- /dev/null +++ b/arrayfire/fn.lgamma.html @@ -0,0 +1,17 @@ +arrayfire::lgamma - Rust + + + +

[][src]Function arrayfire::lgamma

pub fn lgamma<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute the logarithm of absolute values of gamma function

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.load_image.html b/arrayfire/fn.load_image.html new file mode 100644 index 000000000..6bebea68b --- /dev/null +++ b/arrayfire/fn.load_image.html @@ -0,0 +1,24 @@ +arrayfire::load_image - Rust + + + +

[][src]Function arrayfire::load_image

pub fn load_image<T>(filename: String, is_color: bool) -> Array<T> where
    T: HasAfEnum + RealNumber

Load Image into Array

+

Only, Images with 8/16/32 bits per channel can be loaded using this function.

+

Parameters

+
    +
  • filename is aboslute path of the image to be loaded.
  • +
  • is_color indicates if the image file at given path is color or gray scale.
  • +
+

Return Arrays

+

An Array with pixel values loaded from the image

+
\ No newline at end of file diff --git a/arrayfire/fn.load_image_native.html b/arrayfire/fn.load_image_native.html new file mode 100644 index 000000000..c4bc7b60b --- /dev/null +++ b/arrayfire/fn.load_image_native.html @@ -0,0 +1,29 @@ +arrayfire::load_image_native - Rust + + + +

[][src]Function arrayfire::load_image_native

pub fn load_image_native<T>(filename: String) -> Array<T> where
    T: HasAfEnum + ImageNativeType

Load Image into Array in it's native type

+

This load image function allows you to load images as U8, U16 or F32 +depending on the type of input image as shown by the table below.

+ + + + +
Bits per Color (Gray/RGB/RGBA Bits Per Pixel)Array TypeRange
8 ( 8/24/32 BPP)u80 - 255
16 (16/48/64 BPP)u160 - 65535
32 (32/96/128 BPP)f320 - 1
+

Parameters

+
    +
  • filename is name of file to be loaded
  • +
+

Return Arrays

+

An Array with pixel values loaded from the image

+
\ No newline at end of file diff --git a/arrayfire/fn.locate.html b/arrayfire/fn.locate.html new file mode 100644 index 000000000..3cf0b5dbd --- /dev/null +++ b/arrayfire/fn.locate.html @@ -0,0 +1,23 @@ +arrayfire::locate - Rust + + + +

[][src]Function arrayfire::locate

pub fn locate<T: HasAfEnum>(input: &Array<T>) -> Array<u32>

Locate the indices of non-zero elements.

+

The locations are provided by flattening the input into a linear array.

+

Parameters

+
    +
  • input - Input Array
  • +
+

Return Values

+

Array of indices where the input Array has non-zero values.

+
\ No newline at end of file diff --git a/arrayfire/fn.log.html b/arrayfire/fn.log.html new file mode 100644 index 000000000..3d89b2a20 --- /dev/null +++ b/arrayfire/fn.log.html @@ -0,0 +1,17 @@ +arrayfire::log - Rust + + + +

[][src]Function arrayfire::log

pub fn log<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute the natural logarithm

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.log10.html b/arrayfire/fn.log10.html new file mode 100644 index 000000000..c4a50c5b3 --- /dev/null +++ b/arrayfire/fn.log10.html @@ -0,0 +1,17 @@ +arrayfire::log10 - Rust + + + +

[][src]Function arrayfire::log10

pub fn log10<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute logarithm base 10

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.log1p.html b/arrayfire/fn.log1p.html new file mode 100644 index 000000000..c6ec18fee --- /dev/null +++ b/arrayfire/fn.log1p.html @@ -0,0 +1,17 @@ +arrayfire::log1p - Rust + + + +

[][src]Function arrayfire::log1p

pub fn log1p<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute the logarithm of input Array + 1

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.log2.html b/arrayfire/fn.log2.html new file mode 100644 index 000000000..98763ad36 --- /dev/null +++ b/arrayfire/fn.log2.html @@ -0,0 +1,17 @@ +arrayfire::log2 - Rust + + + +

[][src]Function arrayfire::log2

pub fn log2<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute logarithm base 2

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.lookup.html b/arrayfire/fn.lookup.html new file mode 100644 index 000000000..b723ed48a --- /dev/null +++ b/arrayfire/fn.lookup.html @@ -0,0 +1,18 @@ +arrayfire::lookup - Rust + + + +

[][src]Function arrayfire::lookup

pub fn lookup<T, I>(
    input: &Array<T>,
    indices: &Array<I>,
    seq_dim: i32
) -> Array<T> where
    T: HasAfEnum,
    I: HasAfEnum + IndexableType

Lookup(hash) an Array using another Array

+

Given a dimension seq_dim, indices are lookedup in input and returned as a new +Array if found

+
\ No newline at end of file diff --git a/arrayfire/fn.lower.html b/arrayfire/fn.lower.html new file mode 100644 index 000000000..42454e4ee --- /dev/null +++ b/arrayfire/fn.lower.html @@ -0,0 +1,23 @@ +arrayfire::lower - Rust + + + +

[][src]Function arrayfire::lower

pub fn lower<T>(input: &Array<T>, is_unit_diag: bool) -> Array<T> where
    T: HasAfEnum

Create lower triangular matrix

+

Parameters

+
    +
  • input is the input Array
  • +
  • is_unit_diag dictates if the output Array should have 1's along diagonal
  • +
+

Return Values

+

Array

+
\ No newline at end of file diff --git a/arrayfire/fn.lt.html b/arrayfire/fn.lt.html new file mode 100644 index 000000000..a9886407b --- /dev/null +++ b/arrayfire/fn.lt.html @@ -0,0 +1,46 @@ +arrayfire::lt - Rust + + + +

[][src]Function arrayfire::lt

pub fn lt<T, U>(arg1: &T, arg2: &U, batch: bool) -> Array<bool> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Perform less than comparison operation

+

This is a comparison operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the comparison operation a.k.a an Array of boolean values.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.lu.html b/arrayfire/fn.lu.html new file mode 100644 index 000000000..3ce89a43c --- /dev/null +++ b/arrayfire/fn.lu.html @@ -0,0 +1,25 @@ +arrayfire::lu - Rust + + + +

[][src]Function arrayfire::lu

pub fn lu<T>(input: &Array<T>) -> (Array<T>, Array<T>, Array<i32>) where
    T: HasAfEnum + FloatingPoint

Perform LU decomposition

+

Parameters

+
    +
  • input is the input matrix
  • +
+

Return Values

+

A triplet of Arrays.

+

The first Array will contain the lower triangular matrix of the LU decomposition.

+

The second Array will contain the lower triangular matrix of the LU decomposition.

+

The third Array will contain the permutation indices to map the input to the decomposition.

+
\ No newline at end of file diff --git a/arrayfire/fn.lu_inplace.html b/arrayfire/fn.lu_inplace.html new file mode 100644 index 000000000..f318bdd93 --- /dev/null +++ b/arrayfire/fn.lu_inplace.html @@ -0,0 +1,24 @@ +arrayfire::lu_inplace - Rust + + + +

[][src]Function arrayfire::lu_inplace

pub fn lu_inplace<T>(input: &mut Array<T>, is_lapack_piv: bool) -> Array<i32> where
    T: HasAfEnum + FloatingPoint

Perform inplace LU decomposition

+

Parameters

+
    +
  • input contains the input matrix on entry and packed LU decomposition on exit
  • +
  • is_lapack_pic specified if the pivot is returned in original LAPACK compliant format
  • +
+

Return Values

+

An Array with permutation indices to map the input to the decomposition. Since, the input +matrix is modified in place, only pivot values are returned.

+
\ No newline at end of file diff --git a/arrayfire/fn.match_template.html b/arrayfire/fn.match_template.html new file mode 100644 index 000000000..e8e86c7ae --- /dev/null +++ b/arrayfire/fn.match_template.html @@ -0,0 +1,27 @@ +arrayfire::match_template - Rust + + + +

[][src]Function arrayfire::match_template

pub fn match_template<T>(
    search_img: &Array<T>,
    template_img: &Array<T>,
    mtype: MatchType
) -> Array<T::AbsOutType> where
    T: HasAfEnum + ImageFilterType,
    T::AbsOutType: HasAfEnum

Image matching

+

Template matching is an image processing technique to find small patches of an image which +match a given template image. A more in depth discussion on the topic can be found +here.

+

Parameters

+
    +
  • search_img is an array with image data
  • +
  • template_img is the template we are looking for in the image
  • +
  • mtype is metric that should be used to calculate the disparity between window in the image and the template image. It can be one of the values defined by the enum MatchType.
  • +
+

Return Values

+

This function returns an Array with disparity values for the window starting at corresponding pixel position.

+
\ No newline at end of file diff --git a/arrayfire/fn.matmul.html b/arrayfire/fn.matmul.html new file mode 100644 index 000000000..1d169f3cd --- /dev/null +++ b/arrayfire/fn.matmul.html @@ -0,0 +1,25 @@ +arrayfire::matmul - Rust + + + +

[][src]Function arrayfire::matmul

pub fn matmul<T>(
    lhs: &Array<T>,
    rhs: &Array<T>,
    optlhs: MatProp,
    optrhs: MatProp
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Matrix multiple of two Arrays

+

Parameters

+
    +
  • lhs is the Array on left hand side
  • +
  • rhs is the Array on right hand side
  • +
  • optlhs - Transpose left hand side before the function is performed, uses one of the values of MatProp
  • +
  • optrhs - Transpose right hand side before the function is performed, uses one of the values of MatProp
  • +
+

Return Values

+

The result Array of matrix multiplication

+
\ No newline at end of file diff --git a/arrayfire/fn.max.html b/arrayfire/fn.max.html new file mode 100644 index 000000000..87c6cf7e5 --- /dev/null +++ b/arrayfire/fn.max.html @@ -0,0 +1,33 @@ +arrayfire::max - Rust + + + +

[][src]Function arrayfire::max

pub fn max<T>(input: &Array<T>, dim: i32) -> Array<T::InType> where
    T: HasAfEnum,
    T::InType: HasAfEnum

Find maximum among elements of given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

Result Array after finding maximum among elements along a given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, max};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = max(&a, 0);
+print(&b);
+let c = max(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.max_all.html b/arrayfire/fn.max_all.html new file mode 100644 index 000000000..b4e26c5ed --- /dev/null +++ b/arrayfire/fn.max_all.html @@ -0,0 +1,30 @@ +arrayfire::max_all - Rust + + + +

[][src]Function arrayfire::max_all

pub fn max_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::InType as HasAfEnum>::BaseType, <<T as HasAfEnum>::InType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::InType: HasAfEnum,
    <<T as HasAfEnum>::InType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Find maximum among all values of the Array

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the maximum value.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+

Examples

+
+use arrayfire::{Dim4, print, randu, max_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", max_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.max_by_key.html b/arrayfire/fn.max_by_key.html new file mode 100644 index 000000000..74d3988ec --- /dev/null +++ b/arrayfire/fn.max_by_key.html @@ -0,0 +1,24 @@ +arrayfire::max_by_key - Rust + + + +

[][src]Function arrayfire::max_by_key

pub fn max_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Find maximum among values of similar keys along a given dimension

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.max_ragged.html b/arrayfire/fn.max_ragged.html new file mode 100644 index 000000000..cf635af2b --- /dev/null +++ b/arrayfire/fn.max_ragged.html @@ -0,0 +1,49 @@ +arrayfire::max_ragged - Rust + + + +

[][src]Function arrayfire::max_ragged

pub fn max_ragged<T>(
    input: &Array<T>,
    ragged_len: &Array<u32>,
    dim: i32
) -> (Array<T::InType>, Array<u32>) where
    T: HasAfEnum,
    T::InType: HasAfEnum

Max reduction along given axis as per ragged lengths provided

+

Parameters

+
    +
  • input contains the input values to be reduced
  • +
  • ragged_len array containing number of elements to use when reducing along dim
  • +
  • dim is the dimension along which the max operation occurs
  • +
+

Return Values

+

Tuple of Arrays:

+
    +
  • First element: An Array containing the maximum ragged values in input along dim +according to ragged_len
  • +
  • Second Element: An Array containing the locations of the maximum ragged values in +input along dim according to ragged_len
  • +
+

Examples

+
+use arrayfire::{Array, dim4, print, randu, max_ragged};
+let vals: [f32; 6] = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0];
+let rlens: [u32; 2] = [9, 2];
+let varr = Array::new(&vals, dim4![3, 2]);
+let rarr = Array::new(&rlens, dim4![1, 2]);
+print(&varr);
+// 1 4
+// 2 5
+// 3 6
+print(&rarr); // numbers of elements to participate in reduction along given axis
+// 9 2
+let (out, idx) = max_ragged(&varr, &rarr, 0);
+print(&out);
+// 3 5
+print(&idx);
+// 2 1 //Since 3 is max element for given length 9 along first column
+       //Since 5 is max element for given length 2 along second column
+
\ No newline at end of file diff --git a/arrayfire/fn.maxfilt.html b/arrayfire/fn.maxfilt.html new file mode 100644 index 000000000..ea793444e --- /dev/null +++ b/arrayfire/fn.maxfilt.html @@ -0,0 +1,25 @@ +arrayfire::maxfilt - Rust + + + +

[][src]Function arrayfire::maxfilt

pub fn maxfilt<T>(
    input: &Array<T>,
    wlen: u64,
    wwid: u64,
    etype: BorderType
) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Box filter with maximum as box operation

+

Parameters

+
    +
  • input is the input image(Array)
  • +
  • wlen is the horizontal length of the filter
  • +
  • hlen is the vertical length of the filter
  • +
  • etype is enum of type BorderType
  • +
+

Return Values

+

An Array with filtered image data.

+
\ No newline at end of file diff --git a/arrayfire/fn.maxof.html b/arrayfire/fn.maxof.html new file mode 100644 index 000000000..ec2262551 --- /dev/null +++ b/arrayfire/fn.maxof.html @@ -0,0 +1,33 @@ +arrayfire::maxof - Rust + + + +

[][src]Function arrayfire::maxof

pub fn maxof<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise maximum operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.mean.html b/arrayfire/fn.mean.html new file mode 100644 index 000000000..b94a3bde4 --- /dev/null +++ b/arrayfire/fn.mean.html @@ -0,0 +1,24 @@ +arrayfire::mean - Rust + + + +

[][src]Function arrayfire::mean

pub fn mean<T>(input: &Array<T>, dim: i64) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum

Mean along specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.mean_all.html b/arrayfire/fn.mean_all.html new file mode 100644 index 000000000..382ba2629 --- /dev/null +++ b/arrayfire/fn.mean_all.html @@ -0,0 +1,22 @@ +arrayfire::mean_all - Rust + + + +

[][src]Function arrayfire::mean_all

pub fn mean_all<T: HasAfEnum>(input: &Array<T>) -> (f64, f64)

Compute mean of all data

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the stat values.

+
\ No newline at end of file diff --git a/arrayfire/fn.mean_all_weighted.html b/arrayfire/fn.mean_all_weighted.html new file mode 100644 index 000000000..1f4b5b4a7 --- /dev/null +++ b/arrayfire/fn.mean_all_weighted.html @@ -0,0 +1,23 @@ +arrayfire::mean_all_weighted - Rust + + + +

[][src]Function arrayfire::mean_all_weighted

pub fn mean_all_weighted<T, W>(
    input: &Array<T>,
    weights: &Array<W>
) -> (f64, f64) where
    T: HasAfEnum,
    W: HasAfEnum + RealFloating

Compute weighted mean of all data

+

Parameters

+
    +
  • input is the input Array
  • +
  • weights Array has the weights
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the stat values.

+
\ No newline at end of file diff --git a/arrayfire/fn.mean_shift.html b/arrayfire/fn.mean_shift.html new file mode 100644 index 000000000..b3626b3c2 --- /dev/null +++ b/arrayfire/fn.mean_shift.html @@ -0,0 +1,31 @@ +arrayfire::mean_shift - Rust + + + +

[][src]Function arrayfire::mean_shift

pub fn mean_shift<T>(
    input: &Array<T>,
    spatial_sigma: f32,
    chromatic_sigma: f32,
    iter: u32,
    iscolor: bool
) -> Array<T> where
    T: HasAfEnum + RealNumber

Meanshift Filter.

+

A meanshift filter is an edge-preserving smoothing filter commonly used in object tracking and +image segmentation.

+

This filter replaces each pixel in the image with the mean of the values within a given given +color and spatial radius. The meanshift filter is an iterative algorithm that continues until a +maxium number of iterations is met or until the value of the means no longer changes.

+

Parameters

+
    +
  • input array is the input image
  • +
  • spatial_sigma is the spatial variance parameter that decides the filter window
  • +
  • chromatic_sigma is the chromatic variance parameter
  • +
  • iter is the number of iterations filter operation is performed
  • +
  • iscolor indicates if the input is color image or grayscale
  • +
+

Return Values

+

Filtered Image - Array

+
\ No newline at end of file diff --git a/arrayfire/fn.mean_weighted.html b/arrayfire/fn.mean_weighted.html new file mode 100644 index 000000000..b64b9448c --- /dev/null +++ b/arrayfire/fn.mean_weighted.html @@ -0,0 +1,25 @@ +arrayfire::mean_weighted - Rust + + + +

[][src]Function arrayfire::mean_weighted

pub fn mean_weighted<T, W>(
    input: &Array<T>,
    weights: &Array<W>,
    dim: i64
) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum,
    W: HasAfEnum + RealFloating

Weighted mean along specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • weights Array has the weights to be used during the stat computation
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.meanvar.html b/arrayfire/fn.meanvar.html new file mode 100644 index 000000000..c33e7a90c --- /dev/null +++ b/arrayfire/fn.meanvar.html @@ -0,0 +1,30 @@ +arrayfire::meanvar - Rust + + + +

[][src]Function arrayfire::meanvar

pub fn meanvar<T, W>(
    input: &Array<T>,
    weights: &Array<W>,
    bias: VarianceBias,
    dim: i64
) -> (Array<T::MeanOutType>, Array<T::MeanOutType>) where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum,
    W: HasAfEnum + RealFloating

Calculate mean and variance in single API call

+

Parameters

+
    +
  • input is the input Array
  • +
  • weights Array has the weights to be used during the stat computation
  • +
  • bias is type of bias used for variance calculation
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

A tuple of Arrays, whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
    +
  • First Array contains mean values
  • +
  • Second Array contains variance values
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.medfilt.html b/arrayfire/fn.medfilt.html new file mode 100644 index 000000000..e7496cd93 --- /dev/null +++ b/arrayfire/fn.medfilt.html @@ -0,0 +1,25 @@ +arrayfire::medfilt - Rust + + + +

[][src]Function arrayfire::medfilt

pub fn medfilt<T>(
    input: &Array<T>,
    wlen: u64,
    wwid: u64,
    etype: BorderType
) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Median filter

+

Parameters

+
    +
  • input is the input image(Array)
  • +
  • wlen is the horizontal length of the filter
  • +
  • hlen is the vertical length of the filter
  • +
  • etype is enum of type BorderType
  • +
+

Return Values

+

An Array with filtered image data.

+
\ No newline at end of file diff --git a/arrayfire/fn.medfilt1.html b/arrayfire/fn.medfilt1.html new file mode 100644 index 000000000..e43fa1181 --- /dev/null +++ b/arrayfire/fn.medfilt1.html @@ -0,0 +1,24 @@ +arrayfire::medfilt1 - Rust + + + +

[][src]Function arrayfire::medfilt1

pub fn medfilt1<T>(input: &Array<T>, wlen: u64, etype: BorderType) -> Array<T> where
    T: HasAfEnum + ImageFilterType

One dimensional median filter on image

+

Parameters

+
    +
  • input is the input image(Array)
  • +
  • wlen is the horizontal length of the filter
  • +
  • etype is enum of type BorderType
  • +
+

Return Values

+

An Array with filtered image data.

+
\ No newline at end of file diff --git a/arrayfire/fn.median.html b/arrayfire/fn.median.html new file mode 100644 index 000000000..61fdf036d --- /dev/null +++ b/arrayfire/fn.median.html @@ -0,0 +1,24 @@ +arrayfire::median - Rust + + + +

[][src]Function arrayfire::median

pub fn median<T>(input: &Array<T>, dim: i64) -> Array<T> where
    T: HasAfEnum + MedianComputable

Find the median along a given dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is dimension along which median has to be found
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +median needs to be found. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.median_all.html b/arrayfire/fn.median_all.html new file mode 100644 index 000000000..af3c8ca79 --- /dev/null +++ b/arrayfire/fn.median_all.html @@ -0,0 +1,22 @@ +arrayfire::median_all - Rust + + + +

[][src]Function arrayfire::median_all

pub fn median_all<T>(input: &Array<T>) -> (f64, f64) where
    T: HasAfEnum + MedianComputable

Compute median of all data

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the median

+
\ No newline at end of file diff --git a/arrayfire/fn.min.html b/arrayfire/fn.min.html new file mode 100644 index 000000000..4372ec079 --- /dev/null +++ b/arrayfire/fn.min.html @@ -0,0 +1,33 @@ +arrayfire::min - Rust + + + +

[][src]Function arrayfire::min

pub fn min<T>(input: &Array<T>, dim: i32) -> Array<T::InType> where
    T: HasAfEnum,
    T::InType: HasAfEnum

Find minimum among elements of given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

Result Array after finding minimum among elements along a given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, min};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = min(&a, 0);
+print(&b);
+let c = min(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.min_all.html b/arrayfire/fn.min_all.html new file mode 100644 index 000000000..fd9859aec --- /dev/null +++ b/arrayfire/fn.min_all.html @@ -0,0 +1,30 @@ +arrayfire::min_all - Rust + + + +

[][src]Function arrayfire::min_all

pub fn min_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::InType as HasAfEnum>::BaseType, <<T as HasAfEnum>::InType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::InType: HasAfEnum,
    <<T as HasAfEnum>::InType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Find minimum among all values of the Array

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the minimum value.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+

Examples

+
+use arrayfire::{Dim4, print, randu, min_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", min_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.min_by_key.html b/arrayfire/fn.min_by_key.html new file mode 100644 index 000000000..84df76b23 --- /dev/null +++ b/arrayfire/fn.min_by_key.html @@ -0,0 +1,24 @@ +arrayfire::min_by_key - Rust + + + +

[][src]Function arrayfire::min_by_key

pub fn min_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Find minimum among values of similar keys along a given dimension

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.minfilt.html b/arrayfire/fn.minfilt.html new file mode 100644 index 000000000..419cc5fa2 --- /dev/null +++ b/arrayfire/fn.minfilt.html @@ -0,0 +1,25 @@ +arrayfire::minfilt - Rust + + + +

[][src]Function arrayfire::minfilt

pub fn minfilt<T>(
    input: &Array<T>,
    wlen: u64,
    wwid: u64,
    etype: BorderType
) -> Array<T> where
    T: HasAfEnum + ImageFilterType

Box filter with minimum as box operation

+

Parameters

+
    +
  • input is the input image(Array)
  • +
  • wlen is the horizontal length of the filter
  • +
  • hlen is the vertical length of the filter
  • +
  • etype is enum of type BorderType
  • +
+

Return Values

+

An Array with filtered image data.

+
\ No newline at end of file diff --git a/arrayfire/fn.minof.html b/arrayfire/fn.minof.html new file mode 100644 index 000000000..7f8cd5ab1 --- /dev/null +++ b/arrayfire/fn.minof.html @@ -0,0 +1,33 @@ +arrayfire::minof - Rust + + + +

[][src]Function arrayfire::minof

pub fn minof<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise minimum operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.moddims.html b/arrayfire/fn.moddims.html new file mode 100644 index 000000000..b159a4d11 --- /dev/null +++ b/arrayfire/fn.moddims.html @@ -0,0 +1,23 @@ +arrayfire::moddims - Rust + + + +

[][src]Function arrayfire::moddims

pub fn moddims<T>(input: &Array<T>, dims: Dim4) -> Array<T> where
    T: HasAfEnum

Change the shape of the Array

+

Parameters

+
    +
  • input is the input Array
  • +
  • dims is the new dimensions to which the input Array is reshaped to
  • +
+

Return Values

+

Reshaped Array

+
\ No newline at end of file diff --git a/arrayfire/fn.modulo.html b/arrayfire/fn.modulo.html new file mode 100644 index 000000000..5b18ebc6c --- /dev/null +++ b/arrayfire/fn.modulo.html @@ -0,0 +1,46 @@ +arrayfire::modulo - Rust + + + +

[][src]Function arrayfire::modulo

pub fn modulo<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Compute modulo of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.moments.html b/arrayfire/fn.moments.html new file mode 100644 index 000000000..d8add5ad1 --- /dev/null +++ b/arrayfire/fn.moments.html @@ -0,0 +1,24 @@ +arrayfire::moments - Rust + + + +

[][src]Function arrayfire::moments

pub fn moments<T>(input: &Array<T>, moment: MomentType) -> Array<f32> where
    T: HasAfEnum + MomentsComputable

Find Image moments

+

Parameters

+
    +
  • input is the input image
  • +
  • moment is the type of moment to be computed, takes a value of +enum
  • +
+

Return Values

+

Moments Array

+
\ No newline at end of file diff --git a/arrayfire/fn.moments_all.html b/arrayfire/fn.moments_all.html new file mode 100644 index 000000000..52b197fff --- /dev/null +++ b/arrayfire/fn.moments_all.html @@ -0,0 +1,24 @@ +arrayfire::moments_all - Rust + + + +

[][src]Function arrayfire::moments_all

pub fn moments_all<T>(input: &Array<T>, moment: MomentType) -> f64 where
    T: HasAfEnum + MomentsComputable

Find Image moment for whole image

+

Parameters

+
    +
  • input is the input image
  • +
  • moment is the type of moment to be computed, takes a value of +enum
  • +
+

Return Values

+

Moment value of the whole image

+
\ No newline at end of file diff --git a/arrayfire/fn.mul.html b/arrayfire/fn.mul.html new file mode 100644 index 000000000..0361aff51 --- /dev/null +++ b/arrayfire/fn.mul.html @@ -0,0 +1,46 @@ +arrayfire::mul - Rust + + + +

[][src]Function arrayfire::mul

pub fn mul<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Multiplication of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.nearest_neighbour.html b/arrayfire/fn.nearest_neighbour.html new file mode 100644 index 000000000..f9f14d4e9 --- /dev/null +++ b/arrayfire/fn.nearest_neighbour.html @@ -0,0 +1,42 @@ +arrayfire::nearest_neighbour - Rust + + + +

[][src]Function arrayfire::nearest_neighbour

pub fn nearest_neighbour<T>(
    query: &Array<T>,
    train: &Array<T>,
    dist_dim: i64,
    n_dist: u32,
    dist_type: MatchType
) -> (Array<u32>, Array<T::AggregateOutType>) where
    T: HasAfEnum + ImageFilterType,
    T::AggregateOutType: HasAfEnum

Nearest Neighbour.

+

Calculates nearest distances between two 2-dimensional arrays containing features based on the +type of distance computation chosen. Currently, AF_SAD (sum of absolute differences), AF_SSD +(sum of squared differences) and AF_SHD (hamming distance) are supported. One of the arrays +containing the training data and the other the query data. One of the dimensions of the both +arrays must be equal among them, identifying the length of each feature. The other dimension +indicates the total number of features in each of the training and query arrays. Two +1-dimensional arrays are created as results, one containg the smallest N distances of the query +array and another containing the indices of these distances in the training array. The resulting +1-dimensional arrays have length equal to the number of features contained in the query array.

+

Parameters

+
    +
  • query is the array containing the data to be queried
  • +
  • train is the array containing the data used as training data
  • +
  • dist_dim indicates the dimension to analyze for distance (the dimension indicated here must be of equal length for both query and train arrays)
  • +
  • n_dist is the number of smallest distances to return (currently, only values <= 256 are supported)
  • +
  • dist_type is the distance computation type. Currently MatchType::SAD, MatchType::SSD, and MatchType::SHD are supported.
  • +
+

Return Values

+

A tuple of Arrays.

+

The first Array is is an array of MxN size, where M is equal to the number of query features +and N is equal to n_dist. The value at position IxJ indicates the index of the Jth smallest +distance to the Ith query value in the train data array. the index of the Ith smallest distance +of the Mth query.

+

The second Array is is an array of MxN size, where M is equal to the number of query features +and N is equal to n_dist. The value at position IxJ indicates the distance of the Jth smallest +distance to the Ith query value in the train data array based on the dist_type chosen.

+
\ No newline at end of file diff --git a/arrayfire/fn.neq.html b/arrayfire/fn.neq.html new file mode 100644 index 000000000..a5484196e --- /dev/null +++ b/arrayfire/fn.neq.html @@ -0,0 +1,33 @@ +arrayfire::neq - Rust + + + +

[][src]Function arrayfire::neq

pub fn neq<A, B>(
    lhs: &Array<A>,
    rhs: &Array<B>,
    batch: bool
) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise not equals comparison of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.norm.html b/arrayfire/fn.norm.html new file mode 100644 index 000000000..c8c7d97c2 --- /dev/null +++ b/arrayfire/fn.norm.html @@ -0,0 +1,27 @@ +arrayfire::norm - Rust + + + +

[][src]Function arrayfire::norm

pub fn norm<T>(input: &Array<T>, ntype: NormType, p: f64, q: f64) -> f64 where
    T: HasAfEnum + FloatingPoint

Find the norm of a matrix

+

Parameters

+
    +
  • input is the input matrix
  • +
  • ntype is specifies the required norm type using enum NormType
  • +
  • p specifies the value of P when ntype is one of VECTOR_P, MATRIX_L_PQ. It is ignored +for other values of ntype
  • +
  • q specifies the value of Q when ntype is MATRIX_L_PQ. This parameter is ignored if +ntype is anything else.
  • +
+

Return Values

+

A 64-bit floating point value that contains the norm of input matrix.

+
\ No newline at end of file diff --git a/arrayfire/fn.or.html b/arrayfire/fn.or.html new file mode 100644 index 000000000..28c2516dd --- /dev/null +++ b/arrayfire/fn.or.html @@ -0,0 +1,33 @@ +arrayfire::or - Rust + + + +

[][src]Function arrayfire::or

pub fn or<A, B>(lhs: &Array<A>, rhs: &Array<B>, batch: bool) -> Array<A::Output> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 

Elementwise logical or operation of two Arrays

+

This is an element wise binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of lhs and rhs are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of lhs and rhs are different, the value of batch has +to be set to true. In this case, the shapes of lhs and rhs have to satisfy the +following criteria:

    +
      +
    • Same number of elements in lhs and rhs along a given dimension/axis
    • +
    • Only one element in lhs or rhs along a given dimension/axis
    • +
    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.orb.html b/arrayfire/fn.orb.html new file mode 100644 index 000000000..7c72d4b48 --- /dev/null +++ b/arrayfire/fn.orb.html @@ -0,0 +1,34 @@ +arrayfire::orb - Rust + + + +

[][src]Function arrayfire::orb

pub fn orb<T>(
    input: &Array<T>,
    fast_thr: f32,
    max_feat: u32,
    scl_fctr: f32,
    levels: u32,
    blur_img: bool
) -> (Features, Array<T>) where
    T: HasAfEnum + RealFloating

ORB feature descriptor

+

Extract ORB descriptors from FAST features that hold higher Harris responses. FAST does not +compute orientation, thus, orientation of features is calculated using the intensity centroid. +As FAST is also not multi-scale enabled, a multi-scale pyramid is calculated by downsampling +the input image multiple times followed by FAST feature detection on each scale.

+

Parameters

+
    +
  • input - the input image Array
  • +
  • fast_thr - FAST threshold for which a pixel of the circle around the central pixel is +considered to be brighter or darker
  • +
  • max_feat - maximum number of features to hold
  • +
  • scl_fctr - factor to downsample the input image, meaning that each level with hold prior +level dimensions divided by scl_fctr
  • +
  • levels - number of levels to be computed for the image pyramid
  • +
  • blur_img - blur image with a Gaussian filter with sigma=2 before computing descriptors to +increase robustness against noise if true
  • +
+

Return Values

+

This function returns a tuple of Features and Array. The features objects composed of Arrays for x and y coordinates, score, orientation and size of selected features. The Array object is a two dimensional Array of size Nx8 where N is number of selected features.

+
\ No newline at end of file diff --git a/arrayfire/fn.pad.html b/arrayfire/fn.pad.html new file mode 100644 index 000000000..483c546cd --- /dev/null +++ b/arrayfire/fn.pad.html @@ -0,0 +1,25 @@ +arrayfire::pad - Rust + + + +

[][src]Function arrayfire::pad

pub fn pad<T: HasAfEnum>(
    input: &Array<T>,
    begin: Dim4,
    end: Dim4,
    fill_type: BorderType
) -> Array<T>

Pad input Array along borders

+

Parameters

+
    +
  • input is the input array to be padded
  • +
  • begin is padding size before first element along a given dimension
  • +
  • end is padding size after the last element along a given dimension
  • +
  • fill_type indicates what values should be used to fill padded regions
  • +
+

Return Values

+

Padded Array

+
\ No newline at end of file diff --git a/arrayfire/fn.pinverse.html b/arrayfire/fn.pinverse.html new file mode 100644 index 000000000..f1a5819a2 --- /dev/null +++ b/arrayfire/fn.pinverse.html @@ -0,0 +1,30 @@ +arrayfire::pinverse - Rust + + + +

[][src]Function arrayfire::pinverse

pub fn pinverse<T>(
    input: &Array<T>,
    tolerance: f64,
    option: MatProp
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Psuedo Inverse of Matrix

+

Parameters

+
    +
  • input is input matrix
  • +
  • tolerance defines the lower threshold for singular values from SVD
  • +
  • option must be MatProp::NONE (more options might be supported in the future)
  • +
+

Notes:

+
    +
  • Tolerance is not the actual lower threshold, but it is passed in as a +parameter to the calculation of the actual threshold relative to the shape and contents of input.
  • +
  • First, try setting tolerance to 1e-6 for single precision and 1e-12 for double.
  • +
+

Return

+

Pseudo Inverse matrix for the input matrix

+
\ No newline at end of file diff --git a/arrayfire/fn.pow.html b/arrayfire/fn.pow.html new file mode 100644 index 000000000..fab167d8d --- /dev/null +++ b/arrayfire/fn.pow.html @@ -0,0 +1,46 @@ +arrayfire::pow - Rust + + + +

[][src]Function arrayfire::pow

pub fn pow<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Computer power

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.pow2.html b/arrayfire/fn.pow2.html new file mode 100644 index 000000000..4e3a1b9d1 --- /dev/null +++ b/arrayfire/fn.pow2.html @@ -0,0 +1,17 @@ +arrayfire::pow2 - Rust + + + +

[][src]Function arrayfire::pow2

pub fn pow2<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute two raised to the power of value

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.print.html b/arrayfire/fn.print.html new file mode 100644 index 000000000..2e42fc21a --- /dev/null +++ b/arrayfire/fn.print.html @@ -0,0 +1,35 @@ +arrayfire::print - Rust + + + +

[][src]Function arrayfire::print

pub fn print<T: HasAfEnum>(input: &Array<T>)

Print data in the Array

+

Parameters

+
    +
  • input is the Array to be printed
  • +
+

Examples

+
+use arrayfire::{Dim4, print, randu};
+println!("Create a 5-by-3 matrix of random floats on the GPU");
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+

The sample output will look like below:

+
[5 3 1 1]
+    0.7402     0.4464     0.7762
+    0.9210     0.6673     0.2948
+    0.0390     0.1099     0.7140
+    0.9690     0.4702     0.3585
+    0.9251     0.5132     0.6814
+
+
\ No newline at end of file diff --git a/arrayfire/fn.print_gen.html b/arrayfire/fn.print_gen.html new file mode 100644 index 000000000..1b427befc --- /dev/null +++ b/arrayfire/fn.print_gen.html @@ -0,0 +1,40 @@ +arrayfire::print_gen - Rust + + + +

[][src]Function arrayfire::print_gen

pub fn print_gen<T: HasAfEnum>(
    msg: String,
    input: &Array<T>,
    precision: Option<i32>
)

Generalized Array print function

+

Use this function to print Array data with arbitrary preicsion

+

Parameters

+
    +
  • msg is message to be printed before printing the Array data
  • +
  • input is the Array to be printed
  • +
  • precision is data precision with which Array has to be printed
  • +
+

Examples

+
+use arrayfire::{Dim4, print_gen, randu};
+println!("Create a 5-by-3 matrix of random floats on the GPU");
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print_gen(String::from("Random Array"), &a, Some(6));
+

The sample output will look like below:

+
Random Array
+
+[5 3 1 1]
+    0.740276     0.446440     0.776202
+    0.921094     0.667321     0.294810
+    0.039014     0.109939     0.714090
+    0.969058     0.470269     0.358590
+    0.925181     0.513225     0.681451
+
+
\ No newline at end of file diff --git a/arrayfire/fn.print_mem_info.html b/arrayfire/fn.print_mem_info.html new file mode 100644 index 000000000..8a8a180fb --- /dev/null +++ b/arrayfire/fn.print_mem_info.html @@ -0,0 +1,24 @@ +arrayfire::print_mem_info - Rust + + + +

[][src]Function arrayfire::print_mem_info

pub fn print_mem_info(msg: String, device: i32)

Print buffer details from the ArrayFire device manager

+

This information is printed in the form of a table.

+

Parameters

+
    +
  • msg is a message to print before the table
  • +
  • device is the id of the device for which buffer details are to be printed
  • +
+

Return Values

+

None

+
\ No newline at end of file diff --git a/arrayfire/fn.product.html b/arrayfire/fn.product.html new file mode 100644 index 000000000..e34ecd821 --- /dev/null +++ b/arrayfire/fn.product.html @@ -0,0 +1,33 @@ +arrayfire::product - Rust + + + +

[][src]Function arrayfire::product

pub fn product<T>(input: &Array<T>, dim: i32) -> Array<T::ProductOutType> where
    T: HasAfEnum,
    T::ProductOutType: HasAfEnum

Compute product of elements along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

Result Array after multiplying all elements along given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, product};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = product(&a, 0);
+print(&b);
+let c = product(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.product_all.html b/arrayfire/fn.product_all.html new file mode 100644 index 000000000..82c932fa0 --- /dev/null +++ b/arrayfire/fn.product_all.html @@ -0,0 +1,31 @@ +arrayfire::product_all - Rust + + + +

[][src]Function arrayfire::product_all

pub fn product_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType, <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::ProductOutType: HasAfEnum,
    <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Product of all values of the Array

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the product result.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+

Examples

+
+use arrayfire::{Dim4, print, randu, product_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let res = product_all(&a);
+println!("Result : {:?}", res);
+
\ No newline at end of file diff --git a/arrayfire/fn.product_by_key.html b/arrayfire/fn.product_by_key.html new file mode 100644 index 000000000..7d1ea64d2 --- /dev/null +++ b/arrayfire/fn.product_by_key.html @@ -0,0 +1,24 @@ +arrayfire::product_by_key - Rust + + + +

[][src]Function arrayfire::product_by_key

pub fn product_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::ProductOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::ProductOutType: HasAfEnum

Find product of all values with similar keys along a given dimension

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.product_by_key_nan.html b/arrayfire/fn.product_by_key_nan.html new file mode 100644 index 000000000..2050aaa9d --- /dev/null +++ b/arrayfire/fn.product_by_key_nan.html @@ -0,0 +1,26 @@ +arrayfire::product_by_key_nan - Rust + + + +

[][src]Function arrayfire::product_by_key_nan

pub fn product_by_key_nan<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32,
    replace_value: f64
) -> (Array<KeyType>, Array<ValueType::ProductOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::ProductOutType: HasAfEnum

Compute product of all values with similar keys along a given dimension

+

This version of sum by key can replaced all NaN values in the input +with a user provided value before performing the reduction operation.

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.product_nan.html b/arrayfire/fn.product_nan.html new file mode 100644 index 000000000..54d2e5fa3 --- /dev/null +++ b/arrayfire/fn.product_nan.html @@ -0,0 +1,25 @@ +arrayfire::product_nan - Rust + + + +

[][src]Function arrayfire::product_nan

pub fn product_nan<T>(
    input: &Array<T>,
    dim: i32,
    nanval: f64
) -> Array<T::ProductOutType> where
    T: HasAfEnum,
    T::ProductOutType: HasAfEnum

Product of elements along specific dimension using user specified value instead of NAN values

+

Compute product of the values of the input Array along dim dimension after replacing any NAN values in the Array with nanval value.

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is reduction dimension
  • +
  • nanval is value with which all the NAN values of Array are replaced with
  • +
+

Return Values

+

Array that is reduced along given dimension via multiplication operation

+
\ No newline at end of file diff --git a/arrayfire/fn.product_nan_all.html b/arrayfire/fn.product_nan_all.html new file mode 100644 index 000000000..e5c8ea922 --- /dev/null +++ b/arrayfire/fn.product_nan_all.html @@ -0,0 +1,26 @@ +arrayfire::product_nan_all - Rust + + + +

[][src]Function arrayfire::product_nan_all

pub fn product_nan_all<T>(
    input: &Array<T>,
    val: f64
) -> (<<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType, <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::ProductOutType: HasAfEnum,
    <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Product of all values using user provided value for NAN

+

Compute the product of all the values of the input Array after replacing any NAN values with val

+

Parameters

+
    +
  • input is the input Array
  • +
  • val is the val that replaces all NAN values of the Array before reduction operation is +performed.
  • +
+

Return Values

+

A tuple of product result.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+
\ No newline at end of file diff --git a/arrayfire/fn.qr.html b/arrayfire/fn.qr.html new file mode 100644 index 000000000..c47be8d06 --- /dev/null +++ b/arrayfire/fn.qr.html @@ -0,0 +1,26 @@ +arrayfire::qr - Rust + + + +

[][src]Function arrayfire::qr

pub fn qr<T>(input: &Array<T>) -> (Array<T>, Array<T>, Array<T>) where
    T: HasAfEnum + FloatingPoint

Perform QR decomposition

+

Parameters

+
    +
  • input is the input matrix
  • +
+

Return Values

+

A triplet of Arrays.

+

The first Array is the orthogonal matrix from QR decomposition

+

The second Array is the upper triangular matrix from QR decomposition

+

The third Array will contain additional information needed for solving a least squares problem +using q and r

+
\ No newline at end of file diff --git a/arrayfire/fn.qr_inplace.html b/arrayfire/fn.qr_inplace.html new file mode 100644 index 000000000..289f44fa2 --- /dev/null +++ b/arrayfire/fn.qr_inplace.html @@ -0,0 +1,22 @@ +arrayfire::qr_inplace - Rust + + + +

[][src]Function arrayfire::qr_inplace

pub fn qr_inplace<T>(input: &mut Array<T>) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Perform inplace QR decomposition

+

Parameters

+
    +
  • input contains the input matrix on entry, and packed QR decomposition on exit
  • +
+

Return Values

+

An Array with additional information needed for unpacking the data.

+
\ No newline at end of file diff --git a/arrayfire/fn.randn.html b/arrayfire/fn.randn.html new file mode 100644 index 000000000..59d97b046 --- /dev/null +++ b/arrayfire/fn.randn.html @@ -0,0 +1,22 @@ +arrayfire::randn - Rust + + + +

[][src]Function arrayfire::randn

pub fn randn<T>(dims: Dim4) -> Array<T> where
    T: HasAfEnum,
    T: FloatingPoint

Create random numbers from normal distribution

+

Parameters

+
    +
  • dims is the output dimensions
  • +
+

Return Values

+

An Array with random values.

+
\ No newline at end of file diff --git a/arrayfire/fn.random_normal.html b/arrayfire/fn.random_normal.html new file mode 100644 index 000000000..ffbb674da --- /dev/null +++ b/arrayfire/fn.random_normal.html @@ -0,0 +1,23 @@ +arrayfire::random_normal - Rust + + + +

[][src]Function arrayfire::random_normal

pub fn random_normal<T>(dims: Dim4, engine: &RandomEngine) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Generate array of normal numbers using a random engine

+

Parameters

+
    +
  • dims is output array dimensions
  • +
  • engine is an object of type RandomEngine
  • +
+

Return Values

+

An Array with normal numbers generated using random engine

+
\ No newline at end of file diff --git a/arrayfire/fn.random_uniform.html b/arrayfire/fn.random_uniform.html new file mode 100644 index 000000000..6016a73b1 --- /dev/null +++ b/arrayfire/fn.random_uniform.html @@ -0,0 +1,23 @@ +arrayfire::random_uniform - Rust + + + +

[][src]Function arrayfire::random_uniform

pub fn random_uniform<T>(dims: Dim4, engine: &RandomEngine) -> Array<T> where
    T: HasAfEnum

Generate array of uniform numbers using a random engine

+

Parameters

+
    +
  • dims is output array dimensions
  • +
  • engine is an object of type RandomEngine
  • +
+

Return Values

+

An Array with uniform numbers generated using random engine

+
\ No newline at end of file diff --git a/arrayfire/fn.randu.html b/arrayfire/fn.randu.html new file mode 100644 index 000000000..18307a763 --- /dev/null +++ b/arrayfire/fn.randu.html @@ -0,0 +1,22 @@ +arrayfire::randu - Rust + + + +

[][src]Function arrayfire::randu

pub fn randu<T>(dims: Dim4) -> Array<T> where
    T: HasAfEnum

Create random numbers from uniform distribution

+

Parameters

+
    +
  • dims is the output dimensions
  • +
+

Return Values

+

An Array with random values.

+
\ No newline at end of file diff --git a/arrayfire/fn.range.html b/arrayfire/fn.range.html new file mode 100644 index 000000000..9e3857842 --- /dev/null +++ b/arrayfire/fn.range.html @@ -0,0 +1,25 @@ +arrayfire::range - Rust + + + +

[][src]Function arrayfire::range

pub fn range<T: HasAfEnum>(dims: Dim4, seq_dim: i32) -> Array<T>

Create a Range of values

+

Creates an array with [0, n] values along the seq_dim which is tiled across other dimensions.

+

Parameters

+
    +
  • dims is the size of Array
  • +
  • seq_dim is the dimension along which range values are populated, all values along other +dimensions are just repeated
  • +
+

Return Values

+

Array

+
\ No newline at end of file diff --git a/arrayfire/fn.rank.html b/arrayfire/fn.rank.html new file mode 100644 index 000000000..b09fbc039 --- /dev/null +++ b/arrayfire/fn.rank.html @@ -0,0 +1,23 @@ +arrayfire::rank - Rust + + + +

[][src]Function arrayfire::rank

pub fn rank<T>(input: &Array<T>, tol: f64) -> u32 where
    T: HasAfEnum + FloatingPoint

Find rank of a matrix

+

Parameters

+
    +
  • input is the input matrix
  • +
  • tol is the tolerance value
  • +
+

Return Values

+

An unsigned 32-bit integer which is the rank of the input matrix.

+
\ No newline at end of file diff --git a/arrayfire/fn.real.html b/arrayfire/fn.real.html new file mode 100644 index 000000000..4feb1f0a5 --- /dev/null +++ b/arrayfire/fn.real.html @@ -0,0 +1,17 @@ +arrayfire::real - Rust + + + +

[][src]Function arrayfire::real

pub fn real<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Extract real values from a complex Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.regions.html b/arrayfire/fn.regions.html new file mode 100644 index 000000000..341b93ab8 --- /dev/null +++ b/arrayfire/fn.regions.html @@ -0,0 +1,28 @@ +arrayfire::regions - Rust + + + +

[][src]Function arrayfire::regions

pub fn regions<OutType>(
    input: &Array<bool>,
    conn: Connectivity
) -> Array<OutType> where
    OutType: HasAfEnum + RealNumber

Find blobs in given image.

+

Given a binary image (with zero representing background pixels), regions computes a floating +point image where each connected component is labeled from 1 to N, the total number of +components in the image.

+

A component is defined as one or more nonzero pixels that are connected by the specified +connectivity (either Connectivity::FOUR or Connectivity::EIGHT) in two dimensions.

+

Parameters

+
    +
  • input is the input image
  • +
  • conn can take one of the values of Connectivity
  • +
+

Return Values

+

Array with labels indicating different regions

+
\ No newline at end of file diff --git a/arrayfire/fn.register_error_handler.html b/arrayfire/fn.register_error_handler.html new file mode 100644 index 000000000..1f9e46c1e --- /dev/null +++ b/arrayfire/fn.register_error_handler.html @@ -0,0 +1,39 @@ +arrayfire::register_error_handler - Rust + + + +

[][src]Function arrayfire::register_error_handler

pub fn register_error_handler(cb_value: Callback)

Register user provided error handler

+

Examples

+
+#[macro_use]
+extern crate arrayfire;
+
+use arrayfire::{AfError, Callback, info, register_error_handler};
+use std::error::Error;
+
+fn handle_error(error_code: AfError) {
+    match error_code {
+        AfError::SUCCESS => {}, /* No-op */
+        _ => panic!("Error message: {}", error_code),
+    }
+}
+
+fn main() {
+    //Registering the error handler should be the first call
+    //before any other functions are called if your version
+    //of error is to be used for subsequent function calls
+    register_error_handler(Callback::new(handle_error));
+
+    info();
+}
+
\ No newline at end of file diff --git a/arrayfire/fn.rem.html b/arrayfire/fn.rem.html new file mode 100644 index 000000000..c534be2d6 --- /dev/null +++ b/arrayfire/fn.rem.html @@ -0,0 +1,46 @@ +arrayfire::rem - Rust + + + +

[][src]Function arrayfire::rem

pub fn rem<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Compute remainder from two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.reorder.html b/arrayfire/fn.reorder.html new file mode 100644 index 000000000..6566c0c6e --- /dev/null +++ b/arrayfire/fn.reorder.html @@ -0,0 +1,27 @@ +arrayfire::reorder - Rust + + + +

[][src]Function arrayfire::reorder

pub fn reorder<T>(input: &Array<T>, dims: Dim4) -> Array<T> where
    T: HasAfEnum
👎 Deprecated since 3.6.3:

Please use new reorder API

+

Reorder the array in specified order

+

The default order of axes in ArrayFire is axis with smallest distance +between adjacent elements towards an axis with highest distance between +adjacent elements.

+

Parameters

+
    +
  • input is the input Array
  • +
  • dims is the target(output) dimensions
  • +
+

Return Values

+

Array with data reordered as per the new axes order

+
\ No newline at end of file diff --git a/arrayfire/fn.reorder_v2.html b/arrayfire/fn.reorder_v2.html new file mode 100644 index 000000000..f229de8e1 --- /dev/null +++ b/arrayfire/fn.reorder_v2.html @@ -0,0 +1,59 @@ +arrayfire::reorder_v2 - Rust + + + +

[][src]Function arrayfire::reorder_v2

pub fn reorder_v2<T>(
    input: &Array<T>,
    new_axis0: u64,
    new_axis1: u64,
    next_axes: Option<Vec<u64>>
) -> Array<T> where
    T: HasAfEnum

Reorder the array according to the new specified axes

+

Exchanges data within an array such that the requested change in axes is +satisfied. The linear ordering of data within the array is preserved.

+

The default order of axes in ArrayFire is [0 1 2 3] i.e. axis with smallest +distance between adjacent elements followed by next smallest distance axis and +so on. See examples to have a basic idea of how data is re-ordered.

+

Parameters

+
    +
  • input is the input Array
  • +
  • new_axis0 is the new first axis for output
  • +
  • new_axis1 is the new second axis for output
  • +
  • next_axes is the new axes order for output
  • +
+

Return Values

+

Array with data reordered as per the new axes order

+

Examples

+
+use arrayfire::{Array, Dim4, print, randu, reorder_v2};
+let a  = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+let b  = reorder_v2(&a, 1, 0, None);
+print(&a);
+
+// [5 3 1 1]
+//  0.8104     0.2990     0.3014
+//  0.6913     0.2802     0.6938
+//  0.7821     0.1480     0.3513
+//  0.3054     0.1330     0.7176
+//  0.1673     0.4696     0.1181
+
+print(&b);
+// [3 5 1 1]
+//     0.8104     0.6913     0.7821     0.3054     0.1673
+//     0.2990     0.2802     0.1480     0.1330     0.4696
+//     0.3014     0.6938     0.3513     0.7176     0.1181
+
+let c  = reorder_v2(&a, 2, 0, Some(vec![1]));
+print(&c);
+
+// [1 5 3 1]
+//  0.8104     0.6913     0.7821     0.3054     0.1673
+//
+//  0.2990     0.2802     0.1480     0.1330     0.4696
+//
+//  0.3014     0.6938     0.3513     0.7176     0.1181
+
\ No newline at end of file diff --git a/arrayfire/fn.replace.html b/arrayfire/fn.replace.html new file mode 100644 index 000000000..69cf3f9b0 --- /dev/null +++ b/arrayfire/fn.replace.html @@ -0,0 +1,29 @@ +arrayfire::replace - Rust + + + +

[][src]Function arrayfire::replace

pub fn replace<T>(a: &mut Array<T>, cond: &Array<bool>, b: &Array<T>) where
    T: HasAfEnum

Inplace replace in Array based on a condition

+

This function does the C-equivalent of the following statement, except that the operation +happens on a GPU for all elements simultaneously.

+
a = cond ? a : b; /// where cond, a & b are all objects of type Array
+
+

Parameters

+
    +
  • a is the Array whose element will be replaced with element from b if corresponding element in cond Array is True
  • +
  • cond is the Array with conditional values
  • +
  • b is the Array whose element will replace the element in output if corresponding element in cond Array is +False
  • +
+

Return Values

+

None

+
\ No newline at end of file diff --git a/arrayfire/fn.replace_scalar.html b/arrayfire/fn.replace_scalar.html new file mode 100644 index 000000000..80001c5b8 --- /dev/null +++ b/arrayfire/fn.replace_scalar.html @@ -0,0 +1,29 @@ +arrayfire::replace_scalar - Rust + + + +

[][src]Function arrayfire::replace_scalar

pub fn replace_scalar<T>(a: &mut Array<T>, cond: &Array<bool>, b: f64) where
    T: HasAfEnum

Inplace replace in Array based on a condition

+

This function does the C-equivalent of the following statement, except that the operation +happens on a GPU for all elements simultaneously.

+
a = cond ? a : b; /// where cond, a are Arrays and b is scalar(f64)
+
+

Parameters

+
    +
  • a is the Array whose element will be replaced with element from b if corresponding element in cond Array is True
  • +
  • cond is the Array with conditional values
  • +
  • b is the scalar that will replace the element in output if corresponding element in cond Array is +False
  • +
+

Return Values

+

None

+
\ No newline at end of file diff --git a/arrayfire/fn.resize.html b/arrayfire/fn.resize.html new file mode 100644 index 000000000..fdd009ad4 --- /dev/null +++ b/arrayfire/fn.resize.html @@ -0,0 +1,31 @@ +arrayfire::resize - Rust + + + +

[][src]Function arrayfire::resize

pub fn resize<T: HasAfEnum>(
    input: &Array<T>,
    odim0: i64,
    odim1: i64,
    method: InterpType
) -> Array<T>

Resize an Image

+

Resizing an input image can be done using either NEAREST or BILINEAR interpolations. +Nearest interpolation will pick the nearest value to the location, whereas bilinear +interpolation will do a weighted interpolation for calculate the new size.

+

This function does not differentiate between images and data. As long as the array is defined +and the output dimensions are not 0, it will resize any type or size of array.

+

Parameters

+
    +
  • input is the image to be resized
  • +
  • odim0 is the output height
  • +
  • odim1 is the output width
  • +
  • method indicates which interpolation method to use for resizing. It uses enum +InterpType to identify the interpolation method.
  • +
+

Return Values

+

Resized Array

+
\ No newline at end of file diff --git a/arrayfire/fn.rgb2gray.html b/arrayfire/fn.rgb2gray.html new file mode 100644 index 000000000..6253ddb10 --- /dev/null +++ b/arrayfire/fn.rgb2gray.html @@ -0,0 +1,24 @@ +arrayfire::rgb2gray - Rust + + + +

[][src]Function arrayfire::rgb2gray

pub fn rgb2gray<T>(input: &Array<T>, r: f32, g: f32, b: f32) -> Array<T> where
    T: HasAfEnum + GrayRGBConvertible

Color(RGB) to Grayscale conversion

+

Parameters

+
    +
  • r is fraction of red channel to appear in output
  • +
  • g is fraction of green channel to appear in output
  • +
  • b is fraction of blue channel to appear in output
  • +
+

#Return Values

+

An Array with image data in target color space

+
\ No newline at end of file diff --git a/arrayfire/fn.rgb2hsv.html b/arrayfire/fn.rgb2hsv.html new file mode 100644 index 000000000..7defa6408 --- /dev/null +++ b/arrayfire/fn.rgb2hsv.html @@ -0,0 +1,16 @@ +arrayfire::rgb2hsv - Rust + + + +

[][src]Function arrayfire::rgb2hsv

pub fn rgb2hsv<T>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum + RealFloating

RGB to HSV color space conversion

+
\ No newline at end of file diff --git a/arrayfire/fn.rgb2ycbcr.html b/arrayfire/fn.rgb2ycbcr.html new file mode 100644 index 000000000..de4d1fa66 --- /dev/null +++ b/arrayfire/fn.rgb2ycbcr.html @@ -0,0 +1,30 @@ +arrayfire::rgb2ycbcr - Rust + + + +

[][src]Function arrayfire::rgb2ycbcr

pub fn rgb2ycbcr<T>(input: &Array<T>, standard: YCCStd) -> Array<T> where
    T: HasAfEnum + RealFloating

RGB to YCbCr colorspace converter.

+

RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores +individual values for red, green and blue, and hence the 3 values per pixel. A combination of +these three values produces the gamut of unique colors.

+

YCbCr is a family of color spaces used as a part of the color image pipeline in video and +digital photography systems where Y is luma component and Cb & Cr are the blue-difference and +red-difference chroma components.

+

Input array to this function should be of real data in the range [0,1].

+

Parameters

+
    +
  • input is the input image in RGB color space
  • +
  • standard is the target color space - YCbCr standard
  • +
+

Return Values

+

Image(Array) in YCbCr color space

+
\ No newline at end of file diff --git a/arrayfire/fn.root.html b/arrayfire/fn.root.html new file mode 100644 index 000000000..80c0334cf --- /dev/null +++ b/arrayfire/fn.root.html @@ -0,0 +1,46 @@ +arrayfire::root - Rust + + + +

[][src]Function arrayfire::root

pub fn root<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Compute root

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.rotate.html b/arrayfire/fn.rotate.html new file mode 100644 index 000000000..e03c02293 --- /dev/null +++ b/arrayfire/fn.rotate.html @@ -0,0 +1,38 @@ +arrayfire::rotate - Rust + + + +

[][src]Function arrayfire::rotate

pub fn rotate<T: HasAfEnum>(
    input: &Array<T>,
    theta: f64,
    crop: bool,
    method: InterpType
) -> Array<T>

Rotate an Image

+

Rotating an input image can be done using either NEAREST or BILINEAR interpolations. +Nearest interpolation will pick the nearest value to the location, whereas bilinear +interpolation will do a weighted interpolation for calculate the new size.

+

This function does not differentiate between images and data. As long as the array is defined, +it will rotate any type or size of array.

+

The crop option allows you to choose whether to resize the image. If crop is set to false, ie. +the entire rotated image will be a part of the array and the new array size will be greater +than or equal to the input array size. If crop is set to true, then the new array size is same +as the input array size and the data that falls outside the boundaries of the array is +discarded.

+

Any location of the rotated array that does not map to a location of the input array is set to +0.

+

Parameters

+
    +
  • input is the input image
  • +
  • theta is the amount of angle (in radians) image should be rotated
  • +
  • crop indicates if the rotated image has to be cropped to original size
  • +
  • method indicates which interpolation method to use for rotating the image. It uses enum +InterpType to identify the interpolation method.
  • +
+

Return Values

+

Rotated Array

+
\ No newline at end of file diff --git a/arrayfire/fn.round.html b/arrayfire/fn.round.html new file mode 100644 index 000000000..e400a100e --- /dev/null +++ b/arrayfire/fn.round.html @@ -0,0 +1,17 @@ +arrayfire::round - Rust + + + +

[][src]Function arrayfire::round

pub fn round<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Round the values in an Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.row.html b/arrayfire/fn.row.html new file mode 100644 index 000000000..6f6700529 --- /dev/null +++ b/arrayfire/fn.row.html @@ -0,0 +1,24 @@ +arrayfire::row - Rust + + + +

[][src]Function arrayfire::row

pub fn row<T>(input: &Array<T>, row_num: i64) -> Array<T> where
    T: HasAfEnum

Extract row_num row from input Array

+

Examples

+
+use arrayfire::{Dim4, randu, row, print};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+println!("Grab last row of the random matrix");
+print(&a);
+print(&row(&a, 4));
+
\ No newline at end of file diff --git a/arrayfire/fn.rows.html b/arrayfire/fn.rows.html new file mode 100644 index 000000000..8ec003ca8 --- /dev/null +++ b/arrayfire/fn.rows.html @@ -0,0 +1,16 @@ +arrayfire::rows - Rust + + + +

[][src]Function arrayfire::rows

pub fn rows<T>(input: &Array<T>, first: i64, last: i64) -> Array<T> where
    T: HasAfEnum

Get an Array with all rows from first to last in the input Array

+
\ No newline at end of file diff --git a/arrayfire/fn.rsqrt.html b/arrayfire/fn.rsqrt.html new file mode 100644 index 000000000..051b790f1 --- /dev/null +++ b/arrayfire/fn.rsqrt.html @@ -0,0 +1,17 @@ +arrayfire::rsqrt - Rust + + + +

[][src]Function arrayfire::rsqrt

pub fn rsqrt<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute the reciprocal square root

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.sat.html b/arrayfire/fn.sat.html new file mode 100644 index 000000000..a119bf936 --- /dev/null +++ b/arrayfire/fn.sat.html @@ -0,0 +1,22 @@ +arrayfire::sat - Rust + + + +

[][src]Function arrayfire::sat

pub fn sat<T>(input: &Array<T>) -> Array<T::AggregateOutType> where
    T: HasAfEnum + RealNumber,
    T::AggregateOutType: HasAfEnum

Summed area table of an Image

+

Parameters

+
    +
  • input is the input image
  • +
+

Return Values

+

Summed area table (a.k.a Integral Image) of the input image.

+
\ No newline at end of file diff --git a/arrayfire/fn.save_image.html b/arrayfire/fn.save_image.html new file mode 100644 index 000000000..2b4833d86 --- /dev/null +++ b/arrayfire/fn.save_image.html @@ -0,0 +1,21 @@ +arrayfire::save_image - Rust + + + +

[][src]Function arrayfire::save_image

pub fn save_image<T>(filename: String, input: &Array<T>) where
    T: HasAfEnum + RealNumber

Save an Array to an image file

+

Parameters

+
    +
  • filename is the abolute path(includes filename) at which input Array is going to be saved
  • +
  • input is the Array to be stored into the image file
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.save_image_native.html b/arrayfire/fn.save_image_native.html new file mode 100644 index 000000000..dbc71baf6 --- /dev/null +++ b/arrayfire/fn.save_image_native.html @@ -0,0 +1,28 @@ +arrayfire::save_image_native - Rust + + + +

[][src]Function arrayfire::save_image_native

pub fn save_image_native<T>(filename: String, input: &Array<T>) where
    T: HasAfEnum + ImageNativeType

Save an Array without modifications to an image file

+

This function only accepts U8, U16, F32 arrays. These arrays are saved to images without any modifications. You must also note that note all image type support 16 or 32 bit images. The best options for 16 bit images are PNG, PPM and TIFF. The best option for 32 bit images is TIFF. These allow lossless storage.

+

The images stored have the following properties:

+ + + + +
Array TypeBits per Color (Gray/RGB/RGBA Bits Per Pixel)Range
U88 ( 8/24/32 BPP)0 - 255
U1616 (16/48/64 BPP)0 - 65535
F3232 (32/96/128 BPP)0 - 1
+

Parameters

+
    +
  • filename is name of file to be saved
  • +
  • input is the Array to be saved. Should be U8 for saving 8-bit image, U16 for 16-bit image, and F32 for 32-bit image.
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.scale.html b/arrayfire/fn.scale.html new file mode 100644 index 000000000..d15f40ebf --- /dev/null +++ b/arrayfire/fn.scale.html @@ -0,0 +1,29 @@ +arrayfire::scale - Rust + + + +

[][src]Function arrayfire::scale

pub fn scale<T: HasAfEnum>(
    input: &Array<T>,
    scale0: f32,
    scale1: f32,
    odim0: i64,
    odim1: i64,
    method: InterpType
) -> Array<T>

Scale an Image

+

Scale is the same functionality as resize except that the scale function uses the transform kernels. The other difference is that scale does not set boundary values to be the boundary of the input array. Instead these are set to 0.

+

Scale is a special case of the transform function.

+

Parameters

+
    +
  • input is input image
  • +
  • trans0 is amount by which the first dimension is translated
  • +
  • trans1 is amount by which the second dimension is translated
  • +
  • odim0 is the first output dimension
  • +
  • odim1 is the second output dimension
  • +
  • method is the interpolation type (Nearest by default)
  • +
+

Return Values

+

Translated Image(Array).

+
\ No newline at end of file diff --git a/arrayfire/fn.scan.html b/arrayfire/fn.scan.html new file mode 100644 index 000000000..0dd033cae --- /dev/null +++ b/arrayfire/fn.scan.html @@ -0,0 +1,26 @@ +arrayfire::scan - Rust + + + +

[][src]Function arrayfire::scan

pub fn scan<T>(
    input: &Array<T>,
    dim: i32,
    op: BinaryOp,
    inclusive: bool
) -> Array<T::AggregateOutType> where
    T: HasAfEnum,
    T::AggregateOutType: HasAfEnum

Generalized scan

+

Parameters

+
    +
  • input is the data on which scan is to be performed
  • +
  • dim is the dimension along which scan operation is to be performed
  • +
  • op takes value of BinaryOp enum indicating +the type of scan operation
  • +
  • inclusive says if inclusive/exclusive scan is to be performed
  • +
+

Return Values

+

Output Array of scanned input

+
\ No newline at end of file diff --git a/arrayfire/fn.scan_by_key.html b/arrayfire/fn.scan_by_key.html new file mode 100644 index 000000000..7fa857a9c --- /dev/null +++ b/arrayfire/fn.scan_by_key.html @@ -0,0 +1,27 @@ +arrayfire::scan_by_key - Rust + + + +

[][src]Function arrayfire::scan_by_key

pub fn scan_by_key<K, V>(
    key: &Array<K>,
    input: &Array<V>,
    dim: i32,
    op: BinaryOp,
    inclusive: bool
) -> Array<V::AggregateOutType> where
    V: HasAfEnum,
    V::AggregateOutType: HasAfEnum,
    K: HasAfEnum + Scanable

Generalized scan by key

+

Parameters

+
    +
  • key is the key Array
  • +
  • input is the data on which scan is to be performed
  • +
  • dim is the dimension along which scan operation is to be performed
  • +
  • op takes value of BinaryOp enum indicating +the type of scan operation
  • +
  • inclusive says if inclusive/exclusive scan is to be performed
  • +
+

Return Values

+

Output Array of scanned input

+
\ No newline at end of file diff --git a/arrayfire/fn.select.html b/arrayfire/fn.select.html new file mode 100644 index 000000000..017485bd7 --- /dev/null +++ b/arrayfire/fn.select.html @@ -0,0 +1,30 @@ +arrayfire::select - Rust + + + +

[][src]Function arrayfire::select

pub fn select<T>(a: &Array<T>, cond: &Array<bool>, b: &Array<T>) -> Array<T> where
    T: HasAfEnum

Element wise conditional operator for Arrays

+

This function does the C-equivalent of the following statement, except that the operation +happens on a GPU for all elements simultaneously.

+
c = cond ? a : b; /// where cond, a & b are all objects of type Array
+
+

Parameters

+
    +
  • a is the Array whose element will be assigned to output if corresponding element in cond Array is +True
  • +
  • cond is the Array with boolean values
  • +
  • b is the Array whose element will be assigned to output if corresponding element in cond Array is +False
  • +
+

Return Values

+

An Array

+
\ No newline at end of file diff --git a/arrayfire/fn.selectl.html b/arrayfire/fn.selectl.html new file mode 100644 index 000000000..582a25a00 --- /dev/null +++ b/arrayfire/fn.selectl.html @@ -0,0 +1,30 @@ +arrayfire::selectl - Rust + + + +

[][src]Function arrayfire::selectl

pub fn selectl<T>(a: f64, cond: &Array<bool>, b: &Array<T>) -> Array<T> where
    T: HasAfEnum

Element wise conditional operator for Arrays

+

This function does the C-equivalent of the following statement, except that the operation +happens on a GPU for all elements simultaneously.

+
c = cond ? a : b; /// where  a is a scalar(f64) and b is Array
+
+

Parameters

+
    +
  • a is the scalar that is assigned to output if corresponding element in cond Array is +True
  • +
  • cond is the Array with conditional values
  • +
  • b is the Array whose element will be assigned to output if corresponding element in cond Array is +False
  • +
+

Return Values

+

An Array

+
\ No newline at end of file diff --git a/arrayfire/fn.selectr.html b/arrayfire/fn.selectr.html new file mode 100644 index 000000000..a761fce64 --- /dev/null +++ b/arrayfire/fn.selectr.html @@ -0,0 +1,30 @@ +arrayfire::selectr - Rust + + + +

[][src]Function arrayfire::selectr

pub fn selectr<T>(a: &Array<T>, cond: &Array<bool>, b: f64) -> Array<T> where
    T: HasAfEnum

Element wise conditional operator for Arrays

+

This function does the C-equivalent of the following statement, except that the operation +happens on a GPU for all elements simultaneously.

+
c = cond ? a : b; /// where a is Array and b is a scalar(f64)
+
+

Parameters

+
    +
  • a is the Array whose element will be assigned to output if corresponding element in cond Array is +True
  • +
  • cond is the Array with conditional values
  • +
  • b is the scalar that is assigned to output if corresponding element in cond Array is +False
  • +
+

Return Values

+

An Array

+
\ No newline at end of file diff --git a/arrayfire/fn.set_backend.html b/arrayfire/fn.set_backend.html new file mode 100644 index 000000000..5ff73e72f --- /dev/null +++ b/arrayfire/fn.set_backend.html @@ -0,0 +1,20 @@ +arrayfire::set_backend - Rust + + + +

[][src]Function arrayfire::set_backend

pub fn set_backend(backend: Backend)

Toggle backends between cuda, opencl or cpu

+

Parameters

+
    +
  • backend to which to switch to
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.set_col.html b/arrayfire/fn.set_col.html new file mode 100644 index 000000000..f66ad868c --- /dev/null +++ b/arrayfire/fn.set_col.html @@ -0,0 +1,16 @@ +arrayfire::set_col - Rust + + + +

[][src]Function arrayfire::set_col

pub fn set_col<T>(inout: &mut Array<T>, new_col: &Array<T>, col_num: i64) where
    T: HasAfEnum

Set col_num^th col in inout Array to a new Array new_col

+
\ No newline at end of file diff --git a/arrayfire/fn.set_cols.html b/arrayfire/fn.set_cols.html new file mode 100644 index 000000000..f7c351b49 --- /dev/null +++ b/arrayfire/fn.set_cols.html @@ -0,0 +1,16 @@ +arrayfire::set_cols - Rust + + + +

[][src]Function arrayfire::set_cols

pub fn set_cols<T>(
    inout: &mut Array<T>,
    new_cols: &Array<T>,
    first: i64,
    last: i64
) where
    T: HasAfEnum

Set cols from first to last in inout Array with cols from Array new_cols

+
\ No newline at end of file diff --git a/arrayfire/fn.set_cublas_mode.html b/arrayfire/fn.set_cublas_mode.html new file mode 100644 index 000000000..96cfde80e --- /dev/null +++ b/arrayfire/fn.set_cublas_mode.html @@ -0,0 +1,21 @@ +arrayfire::set_cublas_mode - Rust + + + +

[][src]Function arrayfire::set_cublas_mode

pub fn set_cublas_mode(mode: CublasMathMode)

Sets the cuBLAS math mode for the internal handle.

+

See the cuBLAS documentation for additional details

+

Parameters

+ +
\ No newline at end of file diff --git a/arrayfire/fn.set_default_random_engine_type.html b/arrayfire/fn.set_default_random_engine_type.html new file mode 100644 index 000000000..d7ed9529a --- /dev/null +++ b/arrayfire/fn.set_default_random_engine_type.html @@ -0,0 +1,20 @@ +arrayfire::set_default_random_engine_type - Rust + + + +

[][src]Function arrayfire::set_default_random_engine_type

pub fn set_default_random_engine_type(rtype: RandomEngineType)

Set the random engine type for default random number generator

+

Parameters

+ +
\ No newline at end of file diff --git a/arrayfire/fn.set_device.html b/arrayfire/fn.set_device.html new file mode 100644 index 000000000..c484b2d34 --- /dev/null +++ b/arrayfire/fn.set_device.html @@ -0,0 +1,20 @@ +arrayfire::set_device - Rust + + + +

[][src]Function arrayfire::set_device

pub fn set_device(device: i32)

Set active device

+

Parameters

+
    +
  • device is the value of the device identifier which has to be set as active
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.set_fft_plan_cache_size.html b/arrayfire/fn.set_fft_plan_cache_size.html new file mode 100644 index 000000000..ee93026db --- /dev/null +++ b/arrayfire/fn.set_fft_plan_cache_size.html @@ -0,0 +1,19 @@ +arrayfire::set_fft_plan_cache_size - Rust + + + +

[][src]Function arrayfire::set_fft_plan_cache_size

pub fn set_fft_plan_cache_size(cache_size: usize)

Set fft plan cache size

+

Though this is a low overhead function, it is advised not to change +the fft plan cache size a mid program execution unless that is what +you intend to do.

+
\ No newline at end of file diff --git a/arrayfire/fn.set_intersect.html b/arrayfire/fn.set_intersect.html new file mode 100644 index 000000000..226bc064e --- /dev/null +++ b/arrayfire/fn.set_intersect.html @@ -0,0 +1,24 @@ +arrayfire::set_intersect - Rust + + + +

[][src]Function arrayfire::set_intersect

pub fn set_intersect<T>(
    first: &Array<T>,
    second: &Array<T>,
    is_unique: bool
) -> Array<T> where
    T: HasAfEnum + RealNumber

Find intersection of two sets

+

Parameters

+
    +
  • first is one of the input sets
  • +
  • second is the other of the input sets
  • +
  • is_unique is a boolean value indicates if the input sets are unique
  • +
+

Return Values

+

An Array with intersection of the input sets

+
\ No newline at end of file diff --git a/arrayfire/fn.set_manual_eval.html b/arrayfire/fn.set_manual_eval.html new file mode 100644 index 000000000..96513c393 --- /dev/null +++ b/arrayfire/fn.set_manual_eval.html @@ -0,0 +1,21 @@ +arrayfire::set_manual_eval - Rust + + + +

[][src]Function arrayfire::set_manual_eval

pub fn set_manual_eval(flag: bool)

Set eval flag value

+

This function can be used to toggle on/off the manual evaluation of arrays.

+

Parameters

+
    +
  • flag is a boolean value indicating manual evaluation setting
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.set_mem_step_size.html b/arrayfire/fn.set_mem_step_size.html new file mode 100644 index 000000000..323e2e24c --- /dev/null +++ b/arrayfire/fn.set_mem_step_size.html @@ -0,0 +1,22 @@ +arrayfire::set_mem_step_size - Rust + + + +

[][src]Function arrayfire::set_mem_step_size

pub fn set_mem_step_size(step_bytes: usize)

Set the minimum memory chunk size

+

Parameters

+
    +
  • step_bytes is the size of minimum memory chunk in bytes
  • +
+

Return Values

+

None

+
\ No newline at end of file diff --git a/arrayfire/fn.set_row.html b/arrayfire/fn.set_row.html new file mode 100644 index 000000000..0056c66b7 --- /dev/null +++ b/arrayfire/fn.set_row.html @@ -0,0 +1,16 @@ +arrayfire::set_row - Rust + + + +

[][src]Function arrayfire::set_row

pub fn set_row<T>(inout: &mut Array<T>, new_row: &Array<T>, row_num: i64) where
    T: HasAfEnum

Set row_num^th row in inout Array to a new Array new_row

+
\ No newline at end of file diff --git a/arrayfire/fn.set_rows.html b/arrayfire/fn.set_rows.html new file mode 100644 index 000000000..383528b6e --- /dev/null +++ b/arrayfire/fn.set_rows.html @@ -0,0 +1,16 @@ +arrayfire::set_rows - Rust + + + +

[][src]Function arrayfire::set_rows

pub fn set_rows<T>(
    inout: &mut Array<T>,
    new_rows: &Array<T>,
    first: i64,
    last: i64
) where
    T: HasAfEnum

Set rows from first to last in inout Array with rows from Array new_rows

+
\ No newline at end of file diff --git a/arrayfire/fn.set_seed.html b/arrayfire/fn.set_seed.html new file mode 100644 index 000000000..d1a0e3331 --- /dev/null +++ b/arrayfire/fn.set_seed.html @@ -0,0 +1,16 @@ +arrayfire::set_seed - Rust + + + +

[][src]Function arrayfire::set_seed

pub fn set_seed(seed: u64)

Set seed for random number generation

+
\ No newline at end of file diff --git a/arrayfire/fn.set_slice.html b/arrayfire/fn.set_slice.html new file mode 100644 index 000000000..55c05e6e8 --- /dev/null +++ b/arrayfire/fn.set_slice.html @@ -0,0 +1,17 @@ +arrayfire::set_slice - Rust + + + +

[][src]Function arrayfire::set_slice

pub fn set_slice<T>(inout: &mut Array<T>, new_slice: &Array<T>, slice_num: i64) where
    T: HasAfEnum

Set slice slice_num in inout Array to a new Array new_slice

+

Slices indicate that the indexing is along 3rd dimension

+
\ No newline at end of file diff --git a/arrayfire/fn.set_slices.html b/arrayfire/fn.set_slices.html new file mode 100644 index 000000000..e1f02fdaf --- /dev/null +++ b/arrayfire/fn.set_slices.html @@ -0,0 +1,17 @@ +arrayfire::set_slices - Rust + + + +

[][src]Function arrayfire::set_slices

pub fn set_slices<T>(
    inout: &mut Array<T>,
    new_slices: &Array<T>,
    first: i64,
    last: i64
) where
    T: HasAfEnum

Set first to last slices of inout Array to a new Array new_slices

+

Slices indicate that the indexing is along 3rd dimension

+
\ No newline at end of file diff --git a/arrayfire/fn.set_union.html b/arrayfire/fn.set_union.html new file mode 100644 index 000000000..5a41f12b8 --- /dev/null +++ b/arrayfire/fn.set_union.html @@ -0,0 +1,24 @@ +arrayfire::set_union - Rust + + + +

[][src]Function arrayfire::set_union

pub fn set_union<T>(
    first: &Array<T>,
    second: &Array<T>,
    is_unique: bool
) -> Array<T> where
    T: HasAfEnum + RealNumber

Find union of two sets

+

Parameters

+
    +
  • first is one of the input sets
  • +
  • second is the other of the input sets
  • +
  • is_unique is a boolean value indicates if the input sets are unique
  • +
+

Return Values

+

An Array with union of the input sets

+
\ No newline at end of file diff --git a/arrayfire/fn.set_unique.html b/arrayfire/fn.set_unique.html new file mode 100644 index 000000000..fc1a3d380 --- /dev/null +++ b/arrayfire/fn.set_unique.html @@ -0,0 +1,24 @@ +arrayfire::set_unique - Rust + + + +

[][src]Function arrayfire::set_unique

pub fn set_unique<T>(input: &Array<T>, is_sorted: bool) -> Array<T> where
    T: HasAfEnum + RealNumber

Find unique values from a Set

+

Parameters

+
    +
  • input - Input Array
  • +
  • is_sorted - is a boolean variable. If ```True`` +indicates, the input Array is sorted.
  • +
+

Return Values

+

An Array of unique values from the input Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.shift.html b/arrayfire/fn.shift.html new file mode 100644 index 000000000..a5dc3a753 --- /dev/null +++ b/arrayfire/fn.shift.html @@ -0,0 +1,32 @@ +arrayfire::shift - Rust + + + +

[][src]Function arrayfire::shift

pub fn shift<T>(input: &Array<T>, offsets: &[i32; 4]) -> Array<T> where
    T: HasAfEnum

"Circular shift of values along specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • offsets is 4-value tuple that specifies the shift along respective dimension
  • +
+

Return Values

+

An Array with shifted data.

+

Examples

+
+use arrayfire::{Array, Dim4, print, randu, shift};
+let a  = randu::<f32>(Dim4::new(&[5, 1, 1, 1]));
+let _a = shift(&a, &[-1i32, 1 , 1, 1]); //shift data one step backward
+let a_ = shift(&a, &[ 1i32, 1 , 1, 1]); //shift data one step forward
+print(& a);
+print(&_a);
+print(&a_);
+
\ No newline at end of file diff --git a/arrayfire/fn.shiftl.html b/arrayfire/fn.shiftl.html new file mode 100644 index 000000000..1817659de --- /dev/null +++ b/arrayfire/fn.shiftl.html @@ -0,0 +1,46 @@ +arrayfire::shiftl - Rust + + + +

[][src]Function arrayfire::shiftl

pub fn shiftl<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Compute left shift

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.shiftr.html b/arrayfire/fn.shiftr.html new file mode 100644 index 000000000..1b2f0e800 --- /dev/null +++ b/arrayfire/fn.shiftr.html @@ -0,0 +1,46 @@ +arrayfire::shiftr - Rust + + + +

[][src]Function arrayfire::shiftr

pub fn shiftr<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Compute right shift

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.sigmoid.html b/arrayfire/fn.sigmoid.html new file mode 100644 index 000000000..4e7e7ac45 --- /dev/null +++ b/arrayfire/fn.sigmoid.html @@ -0,0 +1,17 @@ +arrayfire::sigmoid - Rust + + + +

[][src]Function arrayfire::sigmoid

pub fn sigmoid<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute sigmoid function

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.sign.html b/arrayfire/fn.sign.html new file mode 100644 index 000000000..24f2f2f24 --- /dev/null +++ b/arrayfire/fn.sign.html @@ -0,0 +1,17 @@ +arrayfire::sign - Rust + + + +

[][src]Function arrayfire::sign

pub fn sign<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Computes the sign of input Array values

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.sin.html b/arrayfire/fn.sin.html new file mode 100644 index 000000000..3c7eb1c87 --- /dev/null +++ b/arrayfire/fn.sin.html @@ -0,0 +1,17 @@ +arrayfire::sin - Rust + + + +

[][src]Function arrayfire::sin

pub fn sin<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute sin

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.sinh.html b/arrayfire/fn.sinh.html new file mode 100644 index 000000000..8e7b5d974 --- /dev/null +++ b/arrayfire/fn.sinh.html @@ -0,0 +1,17 @@ +arrayfire::sinh - Rust + + + +

[][src]Function arrayfire::sinh

pub fn sinh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute sinh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.skew.html b/arrayfire/fn.skew.html new file mode 100644 index 000000000..134716ff5 --- /dev/null +++ b/arrayfire/fn.skew.html @@ -0,0 +1,35 @@ +arrayfire::skew - Rust + + + +

[][src]Function arrayfire::skew

pub fn skew<T: HasAfEnum>(
    input: &Array<T>,
    skew0: f32,
    skew1: f32,
    odim0: i64,
    odim1: i64,
    method: InterpType,
    is_inverse: bool
) -> Array<T>

Skew an image

+

Skew function skews the input array along dim0 by skew0 and along dim1 by skew1. The skew +areguments are in radians. Skewing the data means the data remains parallel along 1 dimensions +but the other dimensions gets moved along based on the angle. If both skew0 and skew1 are +specified, then the data will be skewed along both directions. Explicit output dimensions +can be specified using odim0 and odim1. All new values that do not map to a location of the input array are set to 0.

+

Skew is a special case of the transform function.

+

Parameters

+
    +
  • input is the image to be skewed
  • +
  • skew0 is the factor by which data is skewed along first dimension
  • +
  • skew1 is the factor by which data is skewed along second dimension
  • +
  • odim0 is the output length along first dimension
  • +
  • odim1 is the output length along second dimension
  • +
  • method indicates which interpolation method to use for rotating the image. It uses enum +InterpType to identify the interpolation method.
  • +
  • is_inverse indicates if to apply inverse/forward transform
  • +
+

Return Values

+

Skewed Image

+
\ No newline at end of file diff --git a/arrayfire/fn.slice.html b/arrayfire/fn.slice.html new file mode 100644 index 000000000..dfbda9e58 --- /dev/null +++ b/arrayfire/fn.slice.html @@ -0,0 +1,17 @@ +arrayfire::slice - Rust + + + +

[][src]Function arrayfire::slice

pub fn slice<T>(input: &Array<T>, slice_num: i64) -> Array<T> where
    T: HasAfEnum

Get slice_num^th slice from input Array

+

Slices indicate that the indexing is along 3rd dimension

+
\ No newline at end of file diff --git a/arrayfire/fn.slices.html b/arrayfire/fn.slices.html new file mode 100644 index 000000000..abf7a09e4 --- /dev/null +++ b/arrayfire/fn.slices.html @@ -0,0 +1,17 @@ +arrayfire::slices - Rust + + + +

[][src]Function arrayfire::slices

pub fn slices<T>(input: &Array<T>, first: i64, last: i64) -> Array<T> where
    T: HasAfEnum

Get slices from first to last in input Array

+

Slices indicate that the indexing is along 3rd dimension

+
\ No newline at end of file diff --git a/arrayfire/fn.sobel.html b/arrayfire/fn.sobel.html new file mode 100644 index 000000000..c53701505 --- /dev/null +++ b/arrayfire/fn.sobel.html @@ -0,0 +1,27 @@ +arrayfire::sobel - Rust + + + +

[][src]Function arrayfire::sobel

pub fn sobel<T>(
    input: &Array<T>,
    ker_size: u32
) -> (Array<T::SobelOutType>, Array<T::SobelOutType>) where
    T: HasAfEnum + ImageFilterType,
    T::SobelOutType: HasAfEnum

Sobel Operator

+

Sobel operators perform a 2-D spatial gradient measurement on an image to emphasize the regions +of high spatial frequency, namely edges. A more in depth discussion on it can be found here.

+

Parameters

+
    +
  • input is the input image
  • +
  • ker_size is the kernel size of sobel operator
  • +
+

Return Values

+

A tuple of Arrays.

+

The first Array has derivatives along horizontal direction

+

The second Array has derivatives along vertical direction

+
\ No newline at end of file diff --git a/arrayfire/fn.solve.html b/arrayfire/fn.solve.html new file mode 100644 index 000000000..1054b302b --- /dev/null +++ b/arrayfire/fn.solve.html @@ -0,0 +1,25 @@ +arrayfire::solve - Rust + + + +

[][src]Function arrayfire::solve

pub fn solve<T>(a: &Array<T>, b: &Array<T>, options: MatProp) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Solve a system of equations

+

Parameters

+
    +
  • a is the coefficient matrix
  • +
  • b has the measured values
  • +
  • options determine the various properties of matrix a
  • +
+

The options parameter currently needs to be either NONE, LOWER or UPPER, other values are not supported yet.

+

Return Values

+

An Array which is the matrix of unknown variables

+
\ No newline at end of file diff --git a/arrayfire/fn.solve_lu.html b/arrayfire/fn.solve_lu.html new file mode 100644 index 000000000..3bcb8d67e --- /dev/null +++ b/arrayfire/fn.solve_lu.html @@ -0,0 +1,26 @@ +arrayfire::solve_lu - Rust + + + +

[][src]Function arrayfire::solve_lu

pub fn solve_lu<T>(
    a: &Array<T>,
    piv: &Array<i32>,
    b: &Array<T>,
    options: MatProp
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Solve a system of equations

+

Parameters

+
    +
  • a is the output matrix from packed LU decomposition of the coefficient matrix
  • +
  • piv is the pivot array from packed LU decomposition of the coefficient matrix
  • +
  • b has the measured values
  • +
  • options determine the various properties of matrix a
  • +
+

The options parameter currently needs to be NONE, other values are not supported yet.

+

Return Values

+

An Array which is the matrix of unknown variables

+
\ No newline at end of file diff --git a/arrayfire/fn.sort.html b/arrayfire/fn.sort.html new file mode 100644 index 000000000..8effda8a4 --- /dev/null +++ b/arrayfire/fn.sort.html @@ -0,0 +1,26 @@ +arrayfire::sort - Rust + + + +

[][src]Function arrayfire::sort

pub fn sort<T>(input: &Array<T>, dim: u32, ascending: bool) -> Array<T> where
    T: HasAfEnum + RealNumber

Sort the values in input Arrays

+

Sort an multidimensional Array along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which to sort
  • +
  • ascending - Sorted output will have ascending values if +True and descending order otherwise.
  • +
+

Return Values

+

Sorted Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.sort_by_key.html b/arrayfire/fn.sort_by_key.html new file mode 100644 index 000000000..902fc8501 --- /dev/null +++ b/arrayfire/fn.sort_by_key.html @@ -0,0 +1,28 @@ +arrayfire::sort_by_key - Rust + + + +

[][src]Function arrayfire::sort_by_key

pub fn sort_by_key<K, V>(
    keys: &Array<K>,
    vals: &Array<V>,
    dim: u32,
    ascending: bool
) -> (Array<K>, Array<V>) where
    K: HasAfEnum + RealNumber,
    V: HasAfEnum

Sort the values in input Arrays

+

Sort an multidimensional Array based on keys

+

Parameters

+
    +
  • keys - Array with key values
  • +
  • vals - Array with input values
  • +
  • dim - Dimension along which to sort
  • +
  • ascending - Sorted output will have ascending values if True and descending order otherwise.
  • +
+

Return Values

+

A tuple of Arrays.

+

The first Array contains the keys based on sorted values.

+

The second Array contains the sorted values.

+
\ No newline at end of file diff --git a/arrayfire/fn.sort_index.html b/arrayfire/fn.sort_index.html new file mode 100644 index 000000000..991850eab --- /dev/null +++ b/arrayfire/fn.sort_index.html @@ -0,0 +1,27 @@ +arrayfire::sort_index - Rust + + + +

[][src]Function arrayfire::sort_index

pub fn sort_index<T>(
    input: &Array<T>,
    dim: u32,
    ascending: bool
) -> (Array<T>, Array<u32>) where
    T: HasAfEnum + RealNumber

Sort the values in input Arrays

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which to sort
  • +
  • ascending - Sorted output will have ascending values if +True and descending order otherwise.
  • +
+

Return Values

+

A tuple of Arrays.

+

The first Array contains the keys based on sorted values.

+

The second Array contains the original indices of the sorted values.

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse.html b/arrayfire/fn.sparse.html new file mode 100644 index 000000000..26bc119cd --- /dev/null +++ b/arrayfire/fn.sparse.html @@ -0,0 +1,33 @@ +arrayfire::sparse - Rust + + + +

[][src]Function arrayfire::sparse

pub fn sparse<T>(
    rows: u64,
    cols: u64,
    values: &Array<T>,
    row_indices: &Array<i32>,
    col_indices: &Array<i32>,
    format: SparseFormat
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Create sprase matrix from arrays

+

This function converts Array of values into sparse array +of format sparse format using arrays row_indices and col_indices.

+

Parameters

+
    +
  • rows is the number of rows in the dense matrix
  • +
  • cols is the number of columns in the dense matrix
  • +
  • values is the \ref af::array containing the non-zero elements +`of the matrix
  • +
  • row_indices is the row indices for the sparse array
  • +
  • col_indices is the column indices for the sparse array
  • +
  • format is the storage format of the sparse array
  • +
+

Return Values

+

Array with data in given sparse format

+

Note

+

This function only uses references of the input arrays to create the +sparse data structure and does not perform deep copies.

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_convert_to.html b/arrayfire/fn.sparse_convert_to.html new file mode 100644 index 000000000..4c80c42f9 --- /dev/null +++ b/arrayfire/fn.sparse_convert_to.html @@ -0,0 +1,23 @@ +arrayfire::sparse_convert_to - Rust + + + +

[][src]Function arrayfire::sparse_convert_to

pub fn sparse_convert_to<T>(input: &Array<T>, format: SparseFormat) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Convert between sparse formats

+

Parameters

+
    +
  • input is the input sparse array
  • +
  • format is the target sparse format
  • +
+

Return Values

+

Sparse Array in targe sparse format.

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_from_dense.html b/arrayfire/fn.sparse_from_dense.html new file mode 100644 index 000000000..629e96915 --- /dev/null +++ b/arrayfire/fn.sparse_from_dense.html @@ -0,0 +1,23 @@ +arrayfire::sparse_from_dense - Rust + + + +

[][src]Function arrayfire::sparse_from_dense

pub fn sparse_from_dense<T>(dense: &Array<T>, format: SparseFormat) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Convert dense array to sparse array

+

Parameters

+
    +
  • dense is the dense format array
  • +
  • format is the target sparse format
  • +
+

Return Values

+

Sparse Array

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_from_host.html b/arrayfire/fn.sparse_from_host.html new file mode 100644 index 000000000..0ca27110f --- /dev/null +++ b/arrayfire/fn.sparse_from_host.html @@ -0,0 +1,34 @@ +arrayfire::sparse_from_host - Rust + + + +

[][src]Function arrayfire::sparse_from_host

pub fn sparse_from_host<T>(
    rows: u64,
    cols: u64,
    nzz: u64,
    values: &[T],
    row_indices: &[i32],
    col_indices: &[i32],
    format: SparseFormat
) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Create sprase matrix from data on host memory

+

This function converts host array values into sparse array of format sparse +format using host arrays row_indices and col_indices.

+

Parameters

+
    +
  • rows is the number of rows in the dense matrix
  • +
  • cols is the number of columns in the dense matrix
  • +
  • nzz is the number of non zero elements in the dense matrix
  • +
  • values is the \ref af::array containing the non-zero elements +`of the matrix
  • +
  • row_indices is the row indices for the sparse array
  • +
  • col_indices is the column indices for the sparse array
  • +
  • format is the storage format of the sparse array
  • +
+

Return Values

+

Array with data in given sparse format

+

Note

+

The rules for deep copy/shallow copy/reference are the same as for creating a +regular Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_col_indices.html b/arrayfire/fn.sparse_get_col_indices.html new file mode 100644 index 000000000..7de04b2fe --- /dev/null +++ b/arrayfire/fn.sparse_get_col_indices.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_col_indices - Rust + + + +

[][src]Function arrayfire::sparse_get_col_indices

pub fn sparse_get_col_indices<T>(input: &Array<T>) -> Array<i32> where
    T: HasAfEnum + FloatingPoint

Get cololumn indices Array

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Array with coloumn indices values of sparse Array

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_format.html b/arrayfire/fn.sparse_get_format.html new file mode 100644 index 000000000..b52f5137c --- /dev/null +++ b/arrayfire/fn.sparse_get_format.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_format - Rust + + + +

[][src]Function arrayfire::sparse_get_format

pub fn sparse_get_format<T: HasAfEnum>(input: &Array<T>) -> SparseFormat

Get sparse format

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Sparse array format

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_info.html b/arrayfire/fn.sparse_get_info.html new file mode 100644 index 000000000..14b060f7c --- /dev/null +++ b/arrayfire/fn.sparse_get_info.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_info - Rust + + + +

[][src]Function arrayfire::sparse_get_info

pub fn sparse_get_info<T>(
    input: &Array<T>
) -> (Array<T>, Array<i32>, Array<i32>, SparseFormat) where
    T: HasAfEnum + FloatingPoint

Get sparse Array information

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

A tuple of values, row indices, column indices Arrays and SparseFormat enum.

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_nnz.html b/arrayfire/fn.sparse_get_nnz.html new file mode 100644 index 000000000..5f68bc643 --- /dev/null +++ b/arrayfire/fn.sparse_get_nnz.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_nnz - Rust + + + +

[][src]Function arrayfire::sparse_get_nnz

pub fn sparse_get_nnz<T: HasAfEnum>(input: &Array<T>) -> i64

Get number of non-zero elements in sparse array

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Number of non-zero elements of sparse Array

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_row_indices.html b/arrayfire/fn.sparse_get_row_indices.html new file mode 100644 index 000000000..6393b2985 --- /dev/null +++ b/arrayfire/fn.sparse_get_row_indices.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_row_indices - Rust + + + +

[][src]Function arrayfire::sparse_get_row_indices

pub fn sparse_get_row_indices<T>(input: &Array<T>) -> Array<i32> where
    T: HasAfEnum + FloatingPoint

Get row indices Array

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Array with row indices values of sparse Array

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_get_values.html b/arrayfire/fn.sparse_get_values.html new file mode 100644 index 000000000..cf230887c --- /dev/null +++ b/arrayfire/fn.sparse_get_values.html @@ -0,0 +1,22 @@ +arrayfire::sparse_get_values - Rust + + + +

[][src]Function arrayfire::sparse_get_values

pub fn sparse_get_values<T>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Get values of sparse Array

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Sparse array values

+
\ No newline at end of file diff --git a/arrayfire/fn.sparse_to_dense.html b/arrayfire/fn.sparse_to_dense.html new file mode 100644 index 000000000..c9eba7852 --- /dev/null +++ b/arrayfire/fn.sparse_to_dense.html @@ -0,0 +1,22 @@ +arrayfire::sparse_to_dense - Rust + + + +

[][src]Function arrayfire::sparse_to_dense

pub fn sparse_to_dense<T>(input: &Array<T>) -> Array<T> where
    T: HasAfEnum + FloatingPoint

Convert sparse array to dense array

+

Parameters

+
    +
  • input is the sparse array
  • +
+

Return Values

+

Dense Array

+
\ No newline at end of file diff --git a/arrayfire/fn.sqrt.html b/arrayfire/fn.sqrt.html new file mode 100644 index 000000000..7505a723d --- /dev/null +++ b/arrayfire/fn.sqrt.html @@ -0,0 +1,17 @@ +arrayfire::sqrt - Rust + + + +

[][src]Function arrayfire::sqrt

pub fn sqrt<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute the square root

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.stdev.html b/arrayfire/fn.stdev.html new file mode 100644 index 000000000..0b861206c --- /dev/null +++ b/arrayfire/fn.stdev.html @@ -0,0 +1,25 @@ +arrayfire::stdev - Rust + + + +

[][src]Function arrayfire::stdev

pub fn stdev<T>(input: &Array<T>, dim: i64) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum
👎 Deprecated since 3.8.0:

Please use stdev_v2 API

+

Standard deviation along specified axis

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.stdev_all.html b/arrayfire/fn.stdev_all.html new file mode 100644 index 000000000..467d0fc3e --- /dev/null +++ b/arrayfire/fn.stdev_all.html @@ -0,0 +1,22 @@ +arrayfire::stdev_all - Rust + + + +

[][src]Function arrayfire::stdev_all

pub fn stdev_all<T: HasAfEnum>(input: &Array<T>) -> (f64, f64)

Compute standard deviation of all data

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the stat values.

+
\ No newline at end of file diff --git a/arrayfire/fn.stdev_all_v2.html b/arrayfire/fn.stdev_all_v2.html new file mode 100644 index 000000000..1d6c798c3 --- /dev/null +++ b/arrayfire/fn.stdev_all_v2.html @@ -0,0 +1,23 @@ +arrayfire::stdev_all_v2 - Rust + + + +

[][src]Function arrayfire::stdev_all_v2

pub fn stdev_all_v2<T: HasAfEnum>(
    input: &Array<T>,
    bias_kind: VarianceBias
) -> (f64, f64)

Compute standard deviation of all data

+

Parameters

+
    +
  • input is the input Array
  • +
  • bias_kind of type VarianceBias denotes the type of variane to be computed
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the stat values.

+
\ No newline at end of file diff --git a/arrayfire/fn.stdev_v2.html b/arrayfire/fn.stdev_v2.html new file mode 100644 index 000000000..0ee283c36 --- /dev/null +++ b/arrayfire/fn.stdev_v2.html @@ -0,0 +1,25 @@ +arrayfire::stdev_v2 - Rust + + + +

[][src]Function arrayfire::stdev_v2

pub fn stdev_v2<T>(
    input: &Array<T>,
    bias_kind: VarianceBias,
    dim: i64
) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum

Standard deviation along given axis

+

Parameters

+
    +
  • input is the input Array
  • +
  • bias_kind of type VarianceBias denotes the type of variane to be computed
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.sub.html b/arrayfire/fn.sub.html new file mode 100644 index 000000000..533b5c619 --- /dev/null +++ b/arrayfire/fn.sub.html @@ -0,0 +1,46 @@ +arrayfire::sub - Rust + + + +

[][src]Function arrayfire::sub

pub fn sub<T, U>(
    arg1: &T,
    arg2: &U,
    batch: bool
) -> Array<<<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output> where
    T: Convertable,
    U: Convertable,
    <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
    <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>, 

Subtraction of two Arrays

+

This is a binary elementwise operation.

+

Parameters

+
    +
  • arg1is an argument that implements an internal trait Convertable.
  • +
  • arg2is an argument that implements an internal trait Convertable.
  • +
  • batch is an boolean that indicates if the current operation is an batch operation.
  • +
+

Both parameters arg1 and arg2 can be either an Array or a value of rust integral +type.

+

Return Values

+

An Array with results of the binary operation.

+

Important Notes

+
    +
  • +

    If shape/dimensions of arg1 and arg2 are same, the value of batch parameter +has no effect.

    +
  • +
  • +

    If shape/dimensions of arg1 and arg2 are different, the value of batch has +to be set to true. In this case, the shapes of arg1 and arg2 have to satisfy the +following criteria:

    +
      +
    • Same number of elements in arg1 and arg2 along a given dimension/axis
    • +
    • Only one element in arg1 or arg2 along a given dimension/axis
    • +
    +
  • +
  • +

    The trait Convertable essentially translates to a scalar native type on rust or Array.

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.sum.html b/arrayfire/fn.sum.html new file mode 100644 index 000000000..d3c51d1af --- /dev/null +++ b/arrayfire/fn.sum.html @@ -0,0 +1,33 @@ +arrayfire::sum - Rust + + + +

[][src]Function arrayfire::sum

pub fn sum<T>(input: &Array<T>, dim: i32) -> Array<T::AggregateOutType> where
    T: HasAfEnum,
    T::AggregateOutType: HasAfEnum

Sum elements along a given dimension

+

Parameters

+
    +
  • input - Input Array
  • +
  • dim - Dimension along which the input Array will be reduced
  • +
+

Return Values

+

Result Array after summing all elements along given dimension

+

Examples

+
+use arrayfire::{Dim4, print, randu, sum};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+let b = sum(&a, 0);
+print(&b);
+let c = sum(&a, 1);
+print(&c);
+
\ No newline at end of file diff --git a/arrayfire/fn.sum_all.html b/arrayfire/fn.sum_all.html new file mode 100644 index 000000000..a35a66dce --- /dev/null +++ b/arrayfire/fn.sum_all.html @@ -0,0 +1,30 @@ +arrayfire::sum_all - Rust + + + +

[][src]Function arrayfire::sum_all

pub fn sum_all<T>(
    input: &Array<T>
) -> (<<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType, <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::AggregateOutType: HasAfEnum,
    <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Sum all values of the Array

+

Parameters

+
    +
  • input is the input Array
  • +
+

Return Values

+

A tuple containing the summation result.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+

Examples

+
+use arrayfire::{Dim4, print, randu, sum_all};
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+println!("Result : {:?}", sum_all(&a));
+
\ No newline at end of file diff --git a/arrayfire/fn.sum_by_key.html b/arrayfire/fn.sum_by_key.html new file mode 100644 index 000000000..a95c8dbba --- /dev/null +++ b/arrayfire/fn.sum_by_key.html @@ -0,0 +1,24 @@ +arrayfire::sum_by_key - Rust + + + +

[][src]Function arrayfire::sum_by_key

pub fn sum_by_key<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Find sum of all values with similar keys along a given dimension

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.sum_by_key_nan.html b/arrayfire/fn.sum_by_key_nan.html new file mode 100644 index 000000000..647bd681f --- /dev/null +++ b/arrayfire/fn.sum_by_key_nan.html @@ -0,0 +1,26 @@ +arrayfire::sum_by_key_nan - Rust + + + +

[][src]Function arrayfire::sum_by_key_nan

pub fn sum_by_key_nan<KeyType, ValueType>(
    keys: &Array<KeyType>,
    vals: &Array<ValueType>,
    dim: i32,
    replace_value: f64
) -> (Array<KeyType>, Array<ValueType::AggregateOutType>) where
    KeyType: ReduceByKeyInput,
    ValueType: HasAfEnum,
    ValueType::AggregateOutType: HasAfEnum

Compute sum of all values with similar keys along a given dimension

+

This version of sum by key can replaced all NaN values in the input +with a user provided value before performing the reduction operation.

+

Parameters

+
    +
  • keys - key Array
  • +
  • vals - value Array
  • +
  • dim - Dimension along which the input Array is reduced
  • +
+

Return Values

+

Tuple of Arrays, with output keys and values after reduction

+
\ No newline at end of file diff --git a/arrayfire/fn.sum_nan.html b/arrayfire/fn.sum_nan.html new file mode 100644 index 000000000..4234d8ea8 --- /dev/null +++ b/arrayfire/fn.sum_nan.html @@ -0,0 +1,26 @@ +arrayfire::sum_nan - Rust + + + +

[][src]Function arrayfire::sum_nan

pub fn sum_nan<T>(
    input: &Array<T>,
    dim: i32,
    nanval: f64
) -> Array<T::AggregateOutType> where
    T: HasAfEnum,
    T::AggregateOutType: HasAfEnum

Sum along specific dimension using user specified value instead of NAN values

+

Sum values of the input Array along dim dimension after replacing any NAN values in the +Array with the value of the parameter nanval.

+

Parameters

+
    +
  • input is the input Array
  • +
  • dim is reduction dimension
  • +
  • nanval is value with which all the NAN values of Array are replaced with
  • +
+

Return Values

+

Array that is reduced along given dimension via addition operation

+
\ No newline at end of file diff --git a/arrayfire/fn.sum_nan_all.html b/arrayfire/fn.sum_nan_all.html new file mode 100644 index 000000000..ba58a1879 --- /dev/null +++ b/arrayfire/fn.sum_nan_all.html @@ -0,0 +1,26 @@ +arrayfire::sum_nan_all - Rust + + + +

[][src]Function arrayfire::sum_nan_all

pub fn sum_nan_all<T>(
    input: &Array<T>,
    val: f64
) -> (<<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType, <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType) where
    T: HasAfEnum,
    <T as HasAfEnum>::AggregateOutType: HasAfEnum,
    <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64

Sum all values using user provided value for NAN

+

Sum all the values of the input Array after replacing any NAN values with val.

+

Parameters

+
    +
  • input is the input Array
  • +
  • val is the val that replaces all NAN values of the Array before reduction operation is +performed.
  • +
+

Return Values

+

A tuple of summation result.

+

Note: For non-complex data type Arrays, second value of tuple is zero.

+
\ No newline at end of file diff --git a/arrayfire/fn.susan.html b/arrayfire/fn.susan.html new file mode 100644 index 000000000..7b0f6d527 --- /dev/null +++ b/arrayfire/fn.susan.html @@ -0,0 +1,46 @@ +arrayfire::susan - Rust + + + +

[][src]Function arrayfire::susan

pub fn susan<T>(
    input: &Array<T>,
    radius: u32,
    diff_thr: f32,
    geom_thr: f32,
    feature_ratio: f32,
    edge: u32
) -> Features where
    T: HasAfEnum + ImageFilterType

SUSAN corner detector.

+

SUSAN is an acronym standing for Smallest Univalue Segment Assimilating Nucleus. This method +places a circular disc over the pixel to be tested (a.k.a nucleus) to compute the corner +measure of that corresponding pixel. The region covered by the circular disc is M, and a pixel +in this region is represented by m⃗ ∈M where m⃗ 0 is the nucleus. Every pixel in the region is +compared to the nucleus using the following comparison function:

+

c(m⃗ )=e^−((I(m⃗)−I(m⃗_0))/t)^6

+

where t is radius of the region, I is the brightness of the pixel.

+

Response of SUSAN operator is given by the following equation:

+

R(M) = g−n(M) if n(M) < g

+

R(M) = 0 otherwise,

+

where n(M)=∑c(m⃗) m⃗∈M, g is named the geometric threshold and n is the number of pixels in the +mask which are within t of the nucleus.

+

Importance of the parameters, t and g is explained below:

+
    +
  • t determines how similar points have to be to the nucleusbefore they are considered to be a +part of the univalue segment
  • +
  • g determines the minimum size of the univalue segment. For a large enough g, SUSAN operator +becomes an edge dectector.
  • +
+

Parameters

+
    +
  • input is input grayscale/intensity image
  • +
  • radius is the nucleus radius for each pixel neighborhood
  • +
  • diff_thr is intensity difference threshold a.k.a t from equations in description
  • +
  • geom_thr is the geometric threshold
  • +
  • feature_ratio is maximum number of features that will be returned by the function
  • +
  • edge indicates how many pixels width area should be skipped for corner detection
  • +
+

Return Values

+

An object of type Features composed of arrays for x and y coordinates, score, orientation and size of selected features.

+
\ No newline at end of file diff --git a/arrayfire/fn.svd.html b/arrayfire/fn.svd.html new file mode 100644 index 000000000..5bc16311c --- /dev/null +++ b/arrayfire/fn.svd.html @@ -0,0 +1,30 @@ +arrayfire::svd - Rust + + + +

[][src]Function arrayfire::svd

pub fn svd<T>(input: &Array<T>) -> (Array<T>, Array<T::BaseType>, Array<T>) where
    T: HasAfEnum + FloatingPoint,
    T::BaseType: HasAfEnum

Perform Singular Value Decomposition

+

This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S +such that

+

A = U∗S∗Vt

+

If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M +x N

+

Parameters

+
    +
  • in is the input matrix
  • +
+

Return Values

+

A triplet of Arrays.

+

The first Array is the output array containing U

+

The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix))

+

The third Array is the output array containing V ^ H

+
\ No newline at end of file diff --git a/arrayfire/fn.svd_inplace.html b/arrayfire/fn.svd_inplace.html new file mode 100644 index 000000000..15d3e6489 --- /dev/null +++ b/arrayfire/fn.svd_inplace.html @@ -0,0 +1,31 @@ +arrayfire::svd_inplace - Rust + + + +

[][src]Function arrayfire::svd_inplace

pub fn svd_inplace<T>(
    input: &mut Array<T>
) -> (Array<T>, Array<T::BaseType>, Array<T>) where
    T: HasAfEnum + FloatingPoint,
    T::BaseType: HasAfEnum

Perform Singular Value Decomposition inplace

+

This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S +such that

+

A = U∗S∗Vt

+

If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M +x N

+

Parameters

+
    +
  • in is the input/output matrix. This will contain random data after the function call is +complete.
  • +
+

Return Values

+

A triplet of Arrays.

+

The first Array is the output array containing U

+

The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix))

+

The third Array is the output array containing V ^ H

+
\ No newline at end of file diff --git a/arrayfire/fn.sync.html b/arrayfire/fn.sync.html new file mode 100644 index 000000000..b0724b9a7 --- /dev/null +++ b/arrayfire/fn.sync.html @@ -0,0 +1,22 @@ +arrayfire::sync - Rust + + + +

[][src]Function arrayfire::sync

pub fn sync(device: i32)

Sync all operations on given device

+

Parameters

+
    +
  • device on which the operations are to be synced
  • +
+

Return Values

+

None

+
\ No newline at end of file diff --git a/arrayfire/fn.tan.html b/arrayfire/fn.tan.html new file mode 100644 index 000000000..9af5d287d --- /dev/null +++ b/arrayfire/fn.tan.html @@ -0,0 +1,17 @@ +arrayfire::tan - Rust + + + +

[][src]Function arrayfire::tan

pub fn tan<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute tan

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.tanh.html b/arrayfire/fn.tanh.html new file mode 100644 index 000000000..077633d1c --- /dev/null +++ b/arrayfire/fn.tanh.html @@ -0,0 +1,17 @@ +arrayfire::tanh - Rust + + + +

[][src]Function arrayfire::tanh

pub fn tanh<T: HasAfEnum>(input: &Array<T>) -> Array<T::UnaryOutType> where
    T::UnaryOutType: HasAfEnum

Compute tanh

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.tgamma.html b/arrayfire/fn.tgamma.html new file mode 100644 index 000000000..155aeff72 --- /dev/null +++ b/arrayfire/fn.tgamma.html @@ -0,0 +1,17 @@ +arrayfire::tgamma - Rust + + + +

[][src]Function arrayfire::tgamma

pub fn tgamma<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Compute gamma function

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.tile.html b/arrayfire/fn.tile.html new file mode 100644 index 000000000..dd4f1737d --- /dev/null +++ b/arrayfire/fn.tile.html @@ -0,0 +1,26 @@ +arrayfire::tile - Rust + + + +

[][src]Function arrayfire::tile

pub fn tile<T>(input: &Array<T>, dims: Dim4) -> Array<T> where
    T: HasAfEnum

Tile the input array along specified dimension

+

Tile essentially creates copies of data along each dimension. +The number of copies created is provided by the user on per +axis basis using Dim4

+

Parameters

+
    +
  • input is the input Array
  • +
  • dims is the target(output) dimensions
  • +
+

Return Values

+

Tiled input array as per the tiling dimensions provided

+
\ No newline at end of file diff --git a/arrayfire/fn.topk.html b/arrayfire/fn.topk.html new file mode 100644 index 000000000..6d4a6bf76 --- /dev/null +++ b/arrayfire/fn.topk.html @@ -0,0 +1,33 @@ +arrayfire::topk - Rust + + + +

[][src]Function arrayfire::topk

pub fn topk<T>(
    input: &Array<T>,
    k: u32,
    dim: i32,
    order: TopkFn
) -> (Array<T>, Array<u32>) where
    T: HasAfEnum

Find top k elements along a given dimension

+

This function returns the top k values along a given dimension of the input +array. The indices along with their values are returned.

+

If the input is a multi-dimensional array, the indices will be the index of +the value in that dimension. Order of duplicate values are not preserved.

+

This function is optimized for small values of k. Currently, topk elements +can be found only along dimension 0.

+

Parameters

+
    +
  • input is the values from which top k elements are to be retrieved
  • +
  • k is the number of top elements to be retrieve
  • +
  • dim is the dimension along which the retrieval operation has to performed
  • +
  • order is an enum that can take values of type TopkFn
  • +
+

Return Values

+

A tuple(couple) of Array's with the first Array containing the topk values +with the second Array containing the indices of the topk values in the input +data.

+
\ No newline at end of file diff --git a/arrayfire/fn.transform.html b/arrayfire/fn.transform.html new file mode 100644 index 000000000..cd5ef2254 --- /dev/null +++ b/arrayfire/fn.transform.html @@ -0,0 +1,37 @@ +arrayfire::transform - Rust + + + +

[][src]Function arrayfire::transform

pub fn transform<T: HasAfEnum>(
    input: &Array<T>,
    trans: &Array<f32>,
    odim0: i64,
    odim1: i64,
    method: InterpType,
    is_inverse: bool
) -> Array<T>

Transform(Affine) an Image

+

The transform function uses an affine transform matrix to tranform an input image into a new +one. The transform matrix tf is a 3x2 matrix of type float. The matrix operation is applied to each +location (x, y) that is then transformed to (x', y') of the new array. Hence the transformation +is an element-wise operation.

+

The operation is as below: tf = [r00 r10 r01 r11 t0 t1]

+

x' = x * r00 + y * r01 + t0; y' = x * r10 + y * r11 + t1;

+

Interpolation types of NEAREST, LINEAR, BILINEAR and CUBIC are allowed. Affine transforms can be used for various purposes. translate, scale and skew are +specializations of the transform function.

+

This function can also handle batch operations.

+

Parameters

+
    +
  • input is the image to be resized
  • +
  • trans is the transformation matrix to be used for image transformation
  • +
  • odim0 is the output height
  • +
  • odim1 is the output width
  • +
  • method indicates which interpolation method to use for resizing. It uses enum +InterpType to identify the interpolation method.
  • +
  • is_inverse indicates if to apply inverse/forward transform
  • +
+

Return Values

+

Transformed Array

+
\ No newline at end of file diff --git a/arrayfire/fn.transform_coords.html b/arrayfire/fn.transform_coords.html new file mode 100644 index 000000000..d561b53d0 --- /dev/null +++ b/arrayfire/fn.transform_coords.html @@ -0,0 +1,28 @@ +arrayfire::transform_coords - Rust + + + +

[][src]Function arrayfire::transform_coords

pub fn transform_coords<T>(tf: &Array<T>, d0: f32, d1: f32) -> Array<T> where
    T: HasAfEnum + RealFloating

Transform input coordinates

+

The transform function uses a perspective transform matrix to transform input coordinates +(given as two dimensions) into a coordinates matrix.

+

The output is a 4x2 matrix, indicating the coordinates of the 4 bidimensional transformed +points.

+

Parameters

+
    +
  • tf is the transformation matrix
  • +
  • d0 is the first input dimension
  • +
  • d1 is the second input dimension
  • +
+

Return Values

+

Transformed coordinates

+
\ No newline at end of file diff --git a/arrayfire/fn.translate.html b/arrayfire/fn.translate.html new file mode 100644 index 000000000..f4fdc8908 --- /dev/null +++ b/arrayfire/fn.translate.html @@ -0,0 +1,36 @@ +arrayfire::translate - Rust + + + +

[][src]Function arrayfire::translate

pub fn translate<T: HasAfEnum>(
    input: &Array<T>,
    trans0: f32,
    trans1: f32,
    odim0: i64,
    odim1: i64,
    method: InterpType
) -> Array<T>

Translate an Image

+

Translating an image is moving it along 1st and 2nd dimensions by trans0 and trans1. Positive +values of these will move the data towards negative x and negative y whereas negative values of +these will move the positive right and positive down. See the example below for more.

+

To specify an output dimension, use the odim0 and odim1 for dim0 and dim1 respectively. The +size of 2rd and 3rd dimension is same as input. If odim0 and odim1 and not defined, then the +output dimensions are same as the input dimensions and the data out of bounds will be +discarded.

+

All new values that do not map to a location of the input array are set to 0.

+

Translate is a special case of the transform function.

+

Parameters

+
    +
  • input is input image
  • +
  • trans0 is amount by which the first dimension is translated
  • +
  • trans1 is amount by which the second dimension is translated
  • +
  • odim0 is the first output dimension
  • +
  • odim1 is the second output dimension
  • +
  • method is the interpolation type (Nearest by default)
  • +
+

Return Values

+

Translated Image(Array).

+
\ No newline at end of file diff --git a/arrayfire/fn.transpose.html b/arrayfire/fn.transpose.html new file mode 100644 index 000000000..d538f18ac --- /dev/null +++ b/arrayfire/fn.transpose.html @@ -0,0 +1,24 @@ +arrayfire::transpose - Rust + + + +

[][src]Function arrayfire::transpose

pub fn transpose<T: HasAfEnum>(arr: &Array<T>, conjugate: bool) -> Array<T>

Transpose of a matrix.

+

Parameters

+
    +
  • arr is the input Array
  • +
  • conjugate is a boolean that indicates if the transpose operation needs to be a conjugate +transpose
  • +
+

Return Values

+

Transposed Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.transpose_inplace.html b/arrayfire/fn.transpose_inplace.html new file mode 100644 index 000000000..da4fba1d0 --- /dev/null +++ b/arrayfire/fn.transpose_inplace.html @@ -0,0 +1,22 @@ +arrayfire::transpose_inplace - Rust + + + +

[][src]Function arrayfire::transpose_inplace

pub fn transpose_inplace<T: HasAfEnum>(arr: &mut Array<T>, conjugate: bool)

Inplace transpose of a matrix.

+

Parameters

+
    +
  • arr is the input Array that has to be transposed
  • +
  • conjugate is a boolean that indicates if the transpose operation needs to be a conjugate +transpose
  • +
+
\ No newline at end of file diff --git a/arrayfire/fn.trunc.html b/arrayfire/fn.trunc.html new file mode 100644 index 000000000..0558d0fa6 --- /dev/null +++ b/arrayfire/fn.trunc.html @@ -0,0 +1,17 @@ +arrayfire::trunc - Rust + + + +

[][src]Function arrayfire::trunc

pub fn trunc<T: HasAfEnum>(input: &Array<T>) -> Array<T::AbsOutType> where
    T::AbsOutType: HasAfEnum

Truncate the values in an Array

+

This is an element wise unary operation.

+
\ No newline at end of file diff --git a/arrayfire/fn.unwrap.html b/arrayfire/fn.unwrap.html new file mode 100644 index 000000000..a4a836513 --- /dev/null +++ b/arrayfire/fn.unwrap.html @@ -0,0 +1,75 @@ +arrayfire::unwrap - Rust + + + +

[][src]Function arrayfire::unwrap

pub fn unwrap<T: HasAfEnum>(
    input: &Array<T>,
    wx: i64,
    wy: i64,
    sx: i64,
    sy: i64,
    px: i64,
    py: i64,
    is_column: bool
) -> Array<T>

Generate an array with image windows as columns

+

unwrap takes in an input image along with the window sizes wx and wy, strides sx and sy, and +padding px and py. This function then generates a matrix where each windows is an independent +column.

+

The number of columns (rows if is_column is true) in the output array are govenered by the +number of windows that can be fit along x and y directions. Padding is applied along all 4 +sides of the matrix with px defining the height of the padding along dim 0 and py defining the +width of the padding along dim 1.

+

The first column window is always at the top left corner of the input including padding. If a +window cannot fit before the end of the matrix + padding, it is skipped from the generated +matrix.

+

Padding can take a maximum value of window - 1 repectively for x and y.

+

For multiple channels (3rd and 4th dimension), the generated matrix contains the same number of +channels as the input matrix. Each channel of the output matrix corresponds to the same channel +of the input.

+

Parameters

+
    +
  • input is the input image
  • +
  • wx is the block window size along 0th-dimension between [1, input.dims[0] + px]
  • +
  • wy is the block window size along 1st-dimension between [1, input.dims[1] + py]
  • +
  • sx is the stride along 0th-dimension
  • +
  • sy is the stride along 1st-dimension
  • +
  • px is the padding along 0th-dimension between [0, wx). Padding is applied both before and after.
  • +
  • py is the padding along 1st-dimension between [0, wy). Padding is applied both before and after.
  • +
  • is_column specifies the layout for the unwrapped patch. If is_column is false, the unrapped patch is laid out as a row.
  • +
+

Return Values

+

An Array with image windows as columns

+

Examples

+
A [5 5 1 1]
+10 15 20 25 30
+11 16 21 26 31
+12 17 22 27 32
+13 18 23 28 33
+14 19 24 29 34
+
+// Window 3x3, strides 1x1, padding 0x0
+unwrap(A, 3, 3, 1, 1, 0, 0, False) [9 9 1 1]
+10 11 12 15 16 17 20 21 22
+11 12 13 16 17 18 21 22 23
+12 13 14 17 18 19 22 23 24
+15 16 17 20 21 22 25 26 27
+16 17 18 21 22 23 26 27 28
+17 18 19 22 23 24 27 28 29
+20 21 22 25 26 27 30 31 32
+21 22 23 26 27 28 31 32 33
+22 23 24 27 28 29 32 33 34
+
+// Window 3x3, strides 1x1, padding 1x1
+unwrap(A, 3, 3, 1, 1, 1, 1, False) [9 25 1 1]
+ 0  0  0  0  0  0 10 11 12 13  0 15 16 17 18  0 20 21 22 23  0 25 26 27 28
+ 0  0  0  0  0 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
+ 0  0  0  0  0 11 12 13 14  0 16 17 18 19  0 21 22 23 24  0 26 27 28 29  0
+ 0 10 11 12 13  0 15 16 17 18  0 20 21 22 23  0 25 26 27 28  0 30 31 32 33
+10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
+11 12 13 14  0 16 17 18 19  0 21 22 23 24  0 26 27 28 29  0 31 32 33 34  0
+ 0 15 16 17 18  0 20 21 22 23  0 25 26 27 28  0 30 31 32 33  0  0  0  0  0
+15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  0  0  0  0  0
+16 17 18 19  0 21 22 23 24  0 26 27 28 29  0 31 32 33 34  0  0  0  0  0  0
+
+
\ No newline at end of file diff --git a/arrayfire/fn.upper.html b/arrayfire/fn.upper.html new file mode 100644 index 000000000..57430b09d --- /dev/null +++ b/arrayfire/fn.upper.html @@ -0,0 +1,23 @@ +arrayfire::upper - Rust + + + +

[][src]Function arrayfire::upper

pub fn upper<T>(input: &Array<T>, is_unit_diag: bool) -> Array<T> where
    T: HasAfEnum

Create upper triangular matrix

+

Parameters

+
    +
  • input is the input Array
  • +
  • is_unit_diag dictates if the output Array should have 1's along diagonal
  • +
+

Return Values

+

Array

+
\ No newline at end of file diff --git a/arrayfire/fn.var.html b/arrayfire/fn.var.html new file mode 100644 index 000000000..acfd16a16 --- /dev/null +++ b/arrayfire/fn.var.html @@ -0,0 +1,25 @@ +arrayfire::var - Rust + + + +

[][src]Function arrayfire::var

pub fn var<T>(arr: &Array<T>, isbiased: bool, dim: i64) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum
👎 Deprecated since 3.8.0:

Please use var_v2 API

+

Compute Variance along a specific dimension

+

Parameters

+
    +
  • arr is the input Array
  • +
  • isbiased is boolean denoting population variance(False) or Sample variance(True)
  • +
  • dim is the dimension along which the variance is extracted
  • +
+

Return Values

+

Array with variance of input Array arr along dimension dim.

+
\ No newline at end of file diff --git a/arrayfire/fn.var_all.html b/arrayfire/fn.var_all.html new file mode 100644 index 000000000..57005e541 --- /dev/null +++ b/arrayfire/fn.var_all.html @@ -0,0 +1,24 @@ +arrayfire::var_all - Rust + + + +

[][src]Function arrayfire::var_all

pub fn var_all<T: HasAfEnum>(input: &Array<T>, isbiased: bool) -> (f64, f64)
👎 Deprecated since 3.8.0:

Please use var_all_v2 API

+

Compute Variance of all elements

+

Parameters

+
    +
  • input is the input Array
  • +
  • isbiased is boolean denoting population variance(False) or sample variance(True)
  • +
+

Return Values

+

A tuple of 64-bit floating point values that has the variance of input Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.var_all_v2.html b/arrayfire/fn.var_all_v2.html new file mode 100644 index 000000000..750def705 --- /dev/null +++ b/arrayfire/fn.var_all_v2.html @@ -0,0 +1,23 @@ +arrayfire::var_all_v2 - Rust + + + +

[][src]Function arrayfire::var_all_v2

pub fn var_all_v2<T: HasAfEnum>(
    input: &Array<T>,
    bias_kind: VarianceBias
) -> (f64, f64)

Compute Variance of all elements

+

Parameters

+
    +
  • input is the input Array
  • +
  • bias_kind of type VarianceBias denotes the type of variane to be computed
  • +
+

Return Values

+

A tuple of 64-bit floating point values that has the variance of input Array.

+
\ No newline at end of file diff --git a/arrayfire/fn.var_all_weighted.html b/arrayfire/fn.var_all_weighted.html new file mode 100644 index 000000000..cd21f5a0b --- /dev/null +++ b/arrayfire/fn.var_all_weighted.html @@ -0,0 +1,23 @@ +arrayfire::var_all_weighted - Rust + + + +

[][src]Function arrayfire::var_all_weighted

pub fn var_all_weighted<T, W>(
    input: &Array<T>,
    weights: &Array<W>
) -> (f64, f64) where
    T: HasAfEnum,
    W: HasAfEnum + RealFloating

Compute weighted variance of all data

+

Parameters

+
    +
  • input is the input Array
  • +
  • weights Array has the weights
  • +
+

Return Values

+

A tuple of 64-bit floating point values with the stat values.

+
\ No newline at end of file diff --git a/arrayfire/fn.var_v2.html b/arrayfire/fn.var_v2.html new file mode 100644 index 000000000..efbc99cb8 --- /dev/null +++ b/arrayfire/fn.var_v2.html @@ -0,0 +1,24 @@ +arrayfire::var_v2 - Rust + + + +

[][src]Function arrayfire::var_v2

pub fn var_v2<T>(
    arr: &Array<T>,
    bias_kind: VarianceBias,
    dim: i64
) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum

Compute Variance along a specific dimension

+

Parameters

+
    +
  • arr is the input Array
  • +
  • bias_kind of type VarianceBias denotes the type of variane to be computed
  • +
  • dim is the dimension along which the variance is extracted
  • +
+

Return Values

+

Array with variance of input Array arr along dimension dim.

+
\ No newline at end of file diff --git a/arrayfire/fn.var_weighted.html b/arrayfire/fn.var_weighted.html new file mode 100644 index 000000000..3c8e89a70 --- /dev/null +++ b/arrayfire/fn.var_weighted.html @@ -0,0 +1,25 @@ +arrayfire::var_weighted - Rust + + + +

[][src]Function arrayfire::var_weighted

pub fn var_weighted<T, W>(
    input: &Array<T>,
    weights: &Array<W>,
    dim: i64
) -> Array<T::MeanOutType> where
    T: HasAfEnum,
    T::MeanOutType: HasAfEnum,
    W: HasAfEnum + RealFloating

Weight variance along specified dimension

+

Parameters

+
    +
  • input is the input Array
  • +
  • weights Array has the weights to be used during the stat computation
  • +
  • dim is dimension along which the current stat has to be computed
  • +
+

Return Values

+

An Array whose size is equal to input except along the dimension which +the stat operation is performed. Array size along dim will be reduced to one.

+
\ No newline at end of file diff --git a/arrayfire/fn.wrap.html b/arrayfire/fn.wrap.html new file mode 100644 index 000000000..5381cfadb --- /dev/null +++ b/arrayfire/fn.wrap.html @@ -0,0 +1,34 @@ +arrayfire::wrap - Rust + + + +

[][src]Function arrayfire::wrap

pub fn wrap<T: HasAfEnum>(
    input: &Array<T>,
    ox: i64,
    oy: i64,
    wx: i64,
    wy: i64,
    sx: i64,
    sy: i64,
    px: i64,
    py: i64,
    is_column: bool
) -> Array<T>

Converts unwrapped image to an image

+

Wrap takes an unwrapped image (see unwrap()) and converts it back to an image.

+

The inputs to this function should be the same as the inputs used to generate the unwrapped +image.

+

Parameters

+
    +
  • input is the output of unwrap function call
  • +
  • ox is the 0th-dimension of output image
  • +
  • oy is the 1st-dimension of output image
  • +
  • wx is the block window size along 0th-dimension between
  • +
  • wy is the block window size along 1st-dimension between
  • +
  • sx is the stride along 0th-dimension
  • +
  • sy is the stride along 1st-dimension
  • +
  • px is the padding used along 0th-dimension between [0, wx).
  • +
  • py is the padding used along 1st-dimension between [0, wy).
  • +
  • is_column specifies the layout for the unwrapped patch. If is_column is false, the rows are treated as the patches
  • +
+

Return Values

+

Image(Array) created from unwrapped Image(Array)

+
\ No newline at end of file diff --git a/arrayfire/fn.ycbcr2rgb.html b/arrayfire/fn.ycbcr2rgb.html new file mode 100644 index 000000000..769d0e1ea --- /dev/null +++ b/arrayfire/fn.ycbcr2rgb.html @@ -0,0 +1,37 @@ +arrayfire::ycbcr2rgb - Rust + + + +

[][src]Function arrayfire::ycbcr2rgb

pub fn ycbcr2rgb<T>(input: &Array<T>, standard: YCCStd) -> Array<T> where
    T: HasAfEnum + RealFloating

YCbCr to RGB colorspace converter.

+

YCbCr is a family of color spaces used as a part of the color image pipeline in video and +digital photography systems where Y is luma component and Cb & Cr are the blue-difference and +red-difference chroma components.

+

RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores +individual values for red, green and blue, and hence the 3 values per pixel. A combination of +these three values produces the gamut of unique colors.

+

Input array to this function should be of real data with the following range in their +respective channels.

+
    +
  • Y −> [16,219]
  • +
  • Cb −> [16,240]
  • +
  • Cr −> [16,240]
  • +
+

Parameters

+
    +
  • input is the input image in YCbCr color space
  • +
  • standard is the YCbCr standard in which input image color space is +present.
  • +
+

Return Values

+

Image(Array) in RGB color space

+
\ No newline at end of file diff --git a/arrayfire/graphics/struct.Window.html b/arrayfire/graphics/struct.Window.html new file mode 100644 index 000000000..6f743b64f --- /dev/null +++ b/arrayfire/graphics/struct.Window.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/struct.Window.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.anisotropic_diffusion.html b/arrayfire/image/fn.anisotropic_diffusion.html new file mode 100644 index 000000000..a291a8cb5 --- /dev/null +++ b/arrayfire/image/fn.anisotropic_diffusion.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.anisotropic_diffusion.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.bilateral.html b/arrayfire/image/fn.bilateral.html new file mode 100644 index 000000000..46be125d1 --- /dev/null +++ b/arrayfire/image/fn.bilateral.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.bilateral.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.canny.html b/arrayfire/image/fn.canny.html new file mode 100644 index 000000000..772154072 --- /dev/null +++ b/arrayfire/image/fn.canny.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.canny.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.color_space.html b/arrayfire/image/fn.color_space.html new file mode 100644 index 000000000..7838b31e3 --- /dev/null +++ b/arrayfire/image/fn.color_space.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.color_space.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.confidence_cc.html b/arrayfire/image/fn.confidence_cc.html new file mode 100644 index 000000000..3bd227336 --- /dev/null +++ b/arrayfire/image/fn.confidence_cc.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.confidence_cc.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.dilate.html b/arrayfire/image/fn.dilate.html new file mode 100644 index 000000000..1758660fc --- /dev/null +++ b/arrayfire/image/fn.dilate.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.dilate.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.dilate3.html b/arrayfire/image/fn.dilate3.html new file mode 100644 index 000000000..1056ea395 --- /dev/null +++ b/arrayfire/image/fn.dilate3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.dilate3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.erode.html b/arrayfire/image/fn.erode.html new file mode 100644 index 000000000..a4b370748 --- /dev/null +++ b/arrayfire/image/fn.erode.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.erode.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.erode3.html b/arrayfire/image/fn.erode3.html new file mode 100644 index 000000000..1c3a7dfb3 --- /dev/null +++ b/arrayfire/image/fn.erode3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.erode3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.gaussian_kernel.html b/arrayfire/image/fn.gaussian_kernel.html new file mode 100644 index 000000000..b8902e707 --- /dev/null +++ b/arrayfire/image/fn.gaussian_kernel.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.gaussian_kernel.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.gradient.html b/arrayfire/image/fn.gradient.html new file mode 100644 index 000000000..02133046f --- /dev/null +++ b/arrayfire/image/fn.gradient.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.gradient.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.gray2rgb.html b/arrayfire/image/fn.gray2rgb.html new file mode 100644 index 000000000..1de5e8209 --- /dev/null +++ b/arrayfire/image/fn.gray2rgb.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.gray2rgb.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.hist_equal.html b/arrayfire/image/fn.hist_equal.html new file mode 100644 index 000000000..77de6f6a3 --- /dev/null +++ b/arrayfire/image/fn.hist_equal.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.hist_equal.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.histogram.html b/arrayfire/image/fn.histogram.html new file mode 100644 index 000000000..cb44b6a8f --- /dev/null +++ b/arrayfire/image/fn.histogram.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.histogram.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.hsv2rgb.html b/arrayfire/image/fn.hsv2rgb.html new file mode 100644 index 000000000..b82a5dfcb --- /dev/null +++ b/arrayfire/image/fn.hsv2rgb.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.hsv2rgb.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.inverse_deconv.html b/arrayfire/image/fn.inverse_deconv.html new file mode 100644 index 000000000..12d21845d --- /dev/null +++ b/arrayfire/image/fn.inverse_deconv.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.inverse_deconv.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.is_imageio_available.html b/arrayfire/image/fn.is_imageio_available.html new file mode 100644 index 000000000..fe8019029 --- /dev/null +++ b/arrayfire/image/fn.is_imageio_available.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.is_imageio_available.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.iterative_deconv.html b/arrayfire/image/fn.iterative_deconv.html new file mode 100644 index 000000000..b7343cfcd --- /dev/null +++ b/arrayfire/image/fn.iterative_deconv.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.iterative_deconv.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.load_image.html b/arrayfire/image/fn.load_image.html new file mode 100644 index 000000000..046d8820d --- /dev/null +++ b/arrayfire/image/fn.load_image.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.load_image.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.load_image_native.html b/arrayfire/image/fn.load_image_native.html new file mode 100644 index 000000000..fe1492ab6 --- /dev/null +++ b/arrayfire/image/fn.load_image_native.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.load_image_native.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.maxfilt.html b/arrayfire/image/fn.maxfilt.html new file mode 100644 index 000000000..6f13ae8a4 --- /dev/null +++ b/arrayfire/image/fn.maxfilt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.maxfilt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.mean_shift.html b/arrayfire/image/fn.mean_shift.html new file mode 100644 index 000000000..04514bb49 --- /dev/null +++ b/arrayfire/image/fn.mean_shift.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.mean_shift.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.medfilt.html b/arrayfire/image/fn.medfilt.html new file mode 100644 index 000000000..00ccb2418 --- /dev/null +++ b/arrayfire/image/fn.medfilt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.medfilt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.medfilt1.html b/arrayfire/image/fn.medfilt1.html new file mode 100644 index 000000000..eba36c097 --- /dev/null +++ b/arrayfire/image/fn.medfilt1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.medfilt1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.minfilt.html b/arrayfire/image/fn.minfilt.html new file mode 100644 index 000000000..743f8132e --- /dev/null +++ b/arrayfire/image/fn.minfilt.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.minfilt.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.moments.html b/arrayfire/image/fn.moments.html new file mode 100644 index 000000000..c2136fe69 --- /dev/null +++ b/arrayfire/image/fn.moments.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.moments.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.moments_all.html b/arrayfire/image/fn.moments_all.html new file mode 100644 index 000000000..0324dcf70 --- /dev/null +++ b/arrayfire/image/fn.moments_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.moments_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.regions.html b/arrayfire/image/fn.regions.html new file mode 100644 index 000000000..d4d339a55 --- /dev/null +++ b/arrayfire/image/fn.regions.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.regions.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.resize.html b/arrayfire/image/fn.resize.html new file mode 100644 index 000000000..8af2c0629 --- /dev/null +++ b/arrayfire/image/fn.resize.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.resize.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.rgb2gray.html b/arrayfire/image/fn.rgb2gray.html new file mode 100644 index 000000000..7213add23 --- /dev/null +++ b/arrayfire/image/fn.rgb2gray.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.rgb2gray.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.rgb2hsv.html b/arrayfire/image/fn.rgb2hsv.html new file mode 100644 index 000000000..3b3b08402 --- /dev/null +++ b/arrayfire/image/fn.rgb2hsv.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.rgb2hsv.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.rgb2ycbcr.html b/arrayfire/image/fn.rgb2ycbcr.html new file mode 100644 index 000000000..b1d05dc46 --- /dev/null +++ b/arrayfire/image/fn.rgb2ycbcr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.rgb2ycbcr.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.rotate.html b/arrayfire/image/fn.rotate.html new file mode 100644 index 000000000..abb4a43f7 --- /dev/null +++ b/arrayfire/image/fn.rotate.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.rotate.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.sat.html b/arrayfire/image/fn.sat.html new file mode 100644 index 000000000..a37284f96 --- /dev/null +++ b/arrayfire/image/fn.sat.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sat.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.save_image.html b/arrayfire/image/fn.save_image.html new file mode 100644 index 000000000..0c3e33621 --- /dev/null +++ b/arrayfire/image/fn.save_image.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.save_image.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.save_image_native.html b/arrayfire/image/fn.save_image_native.html new file mode 100644 index 000000000..7087e49df --- /dev/null +++ b/arrayfire/image/fn.save_image_native.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.save_image_native.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.scale.html b/arrayfire/image/fn.scale.html new file mode 100644 index 000000000..a03f9ef64 --- /dev/null +++ b/arrayfire/image/fn.scale.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.scale.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.skew.html b/arrayfire/image/fn.skew.html new file mode 100644 index 000000000..7897b63bb --- /dev/null +++ b/arrayfire/image/fn.skew.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.skew.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.sobel.html b/arrayfire/image/fn.sobel.html new file mode 100644 index 000000000..047782d8f --- /dev/null +++ b/arrayfire/image/fn.sobel.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sobel.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.transform.html b/arrayfire/image/fn.transform.html new file mode 100644 index 000000000..88d4653fa --- /dev/null +++ b/arrayfire/image/fn.transform.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.transform.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.transform_coords.html b/arrayfire/image/fn.transform_coords.html new file mode 100644 index 000000000..4ab2e3cfb --- /dev/null +++ b/arrayfire/image/fn.transform_coords.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.transform_coords.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.translate.html b/arrayfire/image/fn.translate.html new file mode 100644 index 000000000..fe16121e2 --- /dev/null +++ b/arrayfire/image/fn.translate.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.translate.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.unwrap.html b/arrayfire/image/fn.unwrap.html new file mode 100644 index 000000000..721d8f6b3 --- /dev/null +++ b/arrayfire/image/fn.unwrap.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.unwrap.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.wrap.html b/arrayfire/image/fn.wrap.html new file mode 100644 index 000000000..1f0f1f6cf --- /dev/null +++ b/arrayfire/image/fn.wrap.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.wrap.html...

+ + + \ No newline at end of file diff --git a/arrayfire/image/fn.ycbcr2rgb.html b/arrayfire/image/fn.ycbcr2rgb.html new file mode 100644 index 000000000..b6d91a5a6 --- /dev/null +++ b/arrayfire/image/fn.ycbcr2rgb.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ycbcr2rgb.html...

+ + + \ No newline at end of file diff --git a/arrayfire/index.html b/arrayfire/index.html new file mode 100644 index 000000000..a9a71ab71 --- /dev/null +++ b/arrayfire/index.html @@ -0,0 +1,476 @@ +arrayfire - Rust + + + +

[][src]Crate arrayfire

ArrayFire is a high performance software library for parallel computing with an easy-to-use API. +ArrayFire abstracts away much of the details of programming parallel architectures by providing +a high-level container object, the Array, that represents data stored on +a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write +massively parallel applications in a high-level language where they need not be concerned about +low-level optimizations that are frequently required to achieve high throughput on most parallel +architectures. +This crate provides Rust bindings for the ArrayFire library. Given below table shows the rust +bindings compatability with ArrayFire upstream. If you find any bugs, please report them on +github.

+ + +
arrayfire-rust crateArrayFire Upstream
M.m.p1M.m.p2
+

Only, Major(M) & Minor(m) version numbers need to match. p1 and p2 are patch/fix updates +for arrayfire-rust & ArrayFire respectively, and they don't need to match.

+

Please go through our tutorials book for +more explanations on how to use ArrayFire to speedup your code.

+

Macros

+
af_print

Print given message before printing out the Array to standard output

+
constant

Create an array of given shape filled with a single value a.k.a constant array

+
dim4

Create a dim4 object from provided dimensions

+
eval

Macro to evaluate individual Arrays or assignment operations

+
join_many

Join multiple Arrays along a given dimension

+
mem_info

Macro to print the current stats of ArrayFire's memory manager.

+
randn

Create an array of given shape sampled from normal distribution

+
randu

Create an array of given shape sampled from uniform distribution

+
seq

Create a sequence object

+
view

Indexing into an existing Array

+

Structs

+
Array

A multidimensional data container

+
Callback

Structure holding handle to callback function

+
Dim4

Dim4 is used to store Array dimensions

+
Event

RAII construct to manage ArrayFire events

+
Features

A set of Array objects (usually, used in Computer vision context)

+
Indexer

Struct to manage an array of resources of type af_indexer_t(ArrayFire C struct)

+
RandomEngine

Random number generator engine

+
Seq

Sequences are used for indexing Arrays

+
Window

Used to render Array objects

+

Enums

+
AfError

Error codes

+
Backend

Compute/Acceleration Backend

+
BinaryOp

Binary operation types for generalized scan functions

+
BorderType

Helps determine how to pad kernels along borders

+
CannyThresholdType

Canny edge detector threshold operations types

+
ColorMap

Dictates what color map is used for Image rendering

+
ColorSpace

Identify the color space of given image(Array)

+
Connectivity

Used by regions function to identify type of connectivity

+
ConvDomain

Helps determine if convolution is in Spatial or Frequency domain

+
ConvGradientType

Gradient mode for convolution

+
ConvMode

Helps determine the size of output of convolution

+
CublasMathMode

Gradient mode for convolution

+
DType

Types of Array data type

+
DiffusionEq

Anisotropic diffusion flux equation types

+
FluxFn

Diffusion equation types

+
HomographyType

Homography type

+
InterpType

Dictates the interpolation method to be used by a function

+
InverseDeconvAlgo

Inverse Deconvolution Algorithm

+
IterativeDeconvAlgo

Iterative Deconvolution Algorithm

+
MarkerType

Plotting markers

+
MatProp

Helps determine the type of a Matrix

+
MatchType

Error metric used by matchTemplate function

+
MomentType

Image moment types

+
NormType

Norm type

+
RandomEngineType

Random engine types

+
Scalar

Scalar value types

+
SparseFormat

Sparse storage format type

+
TopkFn

topk function ordering

+
VarianceBias

Gradient mode for convolution

+
YCCStd

YCbCr Standards

+

Constants

+
DEFAULT_RANDOM_ENGINE

Default RandomEngine that defaults to PHILOX

+
MERSENNE

Default Mersenne RandomEngine that points to MERSENNE_GP11213

+
PHILOX

Default Philon RandomEngine that points to PHILOX_4X32_10

+
THREEFRY

Default Threefry RandomEngine that points to THREEFRY_2X32_16

+

Traits

+
ComplexFloating

Trait qualifier to accept complex data(numbers)

+
ConfidenceCCInput

Trait qualifier for confidence connected components input

+
ConstGenerator

Type Trait to generate a constant Array of given size

+
Convertable

Type Trait to convert to an Array

+
CovarianceComputable

Trait qualifier for given type indicating computability of covariance

+
DeconvInput

Trait qualifier for confidence connected components input

+
EdgeComputable

Trait qualifier for given type indicating if edge calculations such as +derivates etc. can be performed

+
FloatingPoint

Trait qualifier to accept either real or complex typed data

+
Fromf64

Trait to convert reduction's scalar output to appropriate output type

+
GrayRGBConvertible

Trait qualifier for given type indicating conversion capability between +grayscale and RGB triplets of data

+
HasAfEnum

Types of the data that can be generated using ArrayFire data generation functions.

+
ImageFilterType

Trait qualifier for type of Array's that are accepted +by image processing functions especially filtering algorithms

+
ImageNativeType

Trait qualifier for type of Array's that are accepted +by native image load/save functions.

+
ImplicitPromote

This is an internal trait defined and implemented by ArrayFire +create for rust's built-in types to figure out the data type +binary operation's results.

+
Indexable

Trait bound indicating indexability

+
IndexableType

Trait qualifier for the type of Arrays accepted by scan operations

+
IntegralType

Trait qualifier for given type indicating computability of covariance

+
MedianComputable

Trait qualifier for given type indicating computability of Median

+
MomentsComputable

Trait qualifier for given type indicating computability of Moments

+
RealFloating

Trait qualifier to accept real data(numbers)

+
RealNumber

Trait qualifier indicating it can hold real numbers only

+
ReduceByKeyInput

Trait qualifier for Reduction Key type

+
Scanable

Trait qualifier for the type of Arrays accepted by scan operations

+

Functions

+
HANDLE_ERROR

Default error handler for error code returned by ArrayFire FFI calls

+
abs

Computes absolute value

+
accum

Perform exclusive sum of elements along a given dimension

+
acos

Compute acos

+
acosh

Compute acosh

+
add

Addition of two Arrays

+
all_true

Find if all of the values along a given dimension in the Array are true

+
all_true_all

Find if all values of Array are non-zero

+
all_true_by_key

Key based AND of elements along a given dimension

+
alloc_host

Allocates space using Arrayfire allocator in host memory

+
alloc_pinned

Allocate non-pageable memory on HOST memory

+
and

Elementwise logical and operation of two Arrays

+
anisotropic_diffusion

Anisotropic smoothing filter

+
any_true

Find if any of the values along a given dimension in the Array are true

+
any_true_all

Find if any value of Array is non-zero

+
any_true_by_key

Key based OR of elements along a given dimension

+
approx1

Perform signal interpolation for 1d signals

+
approx1_uniform

Perform signal interpolation for 1d signals along specified dimension

+
approx1_uniform_v2

Same as approx1_uniform but uses existing Array as output

+
approx1_v2

Same as approx1 but uses existing Array as output

+
approx2

Perform signal interpolation for 2d signals

+
approx2_uniform

Perform signal interpolation for 2d signals along a specified dimension

+
approx2_uniform_v2

Same as approx2_uniform but uses existing Array as output

+
approx2_v2

Same as approx2 but uses existing Array as output

+
arg

Computes phase value

+
asin

Compute asin

+
asinh

Compute asinh

+
assign_gen

Assign an Array to another after indexing it using any combination of Array's and Sequence's

+
assign_seq

Assign(copy) content of an Array to another Array indexed by Sequences

+
atan

Compute atan

+
atan2

Calculate atan2 of two Arrays

+
atanh

Compute atanh

+
bilateral

Bilateral Filter.

+
bitand

Elementwise AND(bit) operation of two Arrays

+
bitnot

Perform bitwise complement on all values of Array

+
bitor

Elementwise OR(bit) operation of two Arrays

+
bitxor

Elementwise XOR(bit) operation of two Arrays

+
canny

Canny edge detection operator

+
cbrt

Compute the cube root

+
ceil

Ceil the values in an Array

+
cholesky

Perform Cholesky decomposition

+
cholesky_inplace

Perform inplace Cholesky decomposition

+
clamp

Clamp the values of Array

+
col

Extract col_num col from input Array

+
color_space

Color space conversion

+
cols

Get all cols from first to last in the input Array

+
confidence_cc

Segment image based on similar pixel characteristics

+
conjg

Compute the complex conjugate

+
constant

Create an Array with constant value

+
convolve1

1d convolution

+
convolve2

2d convolution

+
convolve2_gradient_nn

Backward pass gradient of 2D convolution

+
convolve2_nn

Convolution Integral for two dimensional data

+
convolve2_sep

Separable convolution for 2d signals

+
convolve3

3d convolution

+
corrcoef

Compute correlation coefficient

+
cos

Compute cos

+
cosh

Compute cosh

+
count

Count number of non-zero elements along a given dimension

+
count_all

Count number of non-zero values in the Array

+
count_by_key

Find total count of elements with similar keys along a given dimension

+
covDeprecated

Compute covariance of two Arrays

+
cov_v2

Compute covariance of two Arrays

+
cplx

Create a complex Array from real Array

+
cplx2

Create complex array from two Arrays

+
det

Find the determinant of the matrix

+
device_count

Get total number of available devices

+
device_gc

Call the garbage collection routine

+
device_info

Gets the information about device and platform as strings.

+
device_mem_info

Get memory information from the memory manager for the current active device

+
diag_create

Create a diagonal matrix

+
diag_extract

Extract diagonal from a given Matrix

+
diff1

Calculate first order numerical difference along a given dimension

+
diff2

Calculate second order numerical difference along a given dimension

+
dilate

Dilate an Image

+
dilate3

Dilate a Volume

+
div

Division of two Arrays

+
dog

Difference of Gaussians.

+
dot

Calculate the dot product of vectors.

+
eq

Perform equals comparison operation

+
erf

Compute error function value

+
erfc

Compute the complementary error function value

+
erode

Erode an Image

+
erode3

Erode a Volume

+
eval_multiple

evaluate multiple arrays

+
exp

Compute e raised to the power of value

+
expm1

Compute e raised to the power of value -1

+
factorial

Compute the factorial

+
fast

Fast feature detector

+
fft

Fast fourier transform for 1d signals

+
fft2

Fast fourier transform for 2d signals

+
fft2_c2r

2d Complex to Real fast fourier transform

+
fft2_inplace

In place 2d dimensional Fast fourier transform

+
fft2_r2c

2d Real to Complex fast fourier transform

+
fft3

Fast fourier transform for 3d signals

+
fft3_c2r

3d Complex to Real fast fourier transform

+
fft3_inplace

In place 3d dimensional Fast fourier transform

+
fft3_r2c

3d Real to Complex fast fourier transform

+
fft_c2r

1d Complex to Real fast fourier transform

+
fft_convolve1

1d convolution using fast-fourier transform

+
fft_convolve2

2d convolution using fast-fourier transform

+
fft_convolve3

3d convolution using fast-fourier transform

+
fft_inplace

In place 1d dimensional Fast fourier transform

+
fft_r2c

1d Real to Complex fast fourier transform

+
fir

Finite impulse filter

+
flat

Flatten the multidimensional Array to an 1D Array

+
flip

Flip the Array

+
floor

Floor the values in an Array

+
free_host

Frees memory allocated by Arrayfire allocator in host memory

+
free_pinned

Free the pointer returned by alloc_pinned

+
gaussian_kernel

Creates a Gaussian Kernel.

+
ge

Perform greater than equals comparison operation

+
gemm

BLAS general matrix multiply (GEMM) of two Array objects

+
get_active_backend

Get current active backend

+
get_available_backends

Get the available backends

+
get_backend_count

Get the available backend count

+
get_default_random_engine

Get default random engine

+
get_device

Get the current active device id

+
get_last_error

Fetch last error description as String

+
get_mem_step_size

Get the minimum memory chunk size

+
get_revision

Get ArrayFire Revision (commit) information of the library.

+
get_seed

Get the seed of random number generator

+
get_size

Get size, in bytes, of the arrayfire native type

+
get_version

Get ArrayFire Version Number

+
gradient

Calculate the gradients

+
gray2rgb

Grayscale to Color(RGB) conversion

+
gt

Perform greater than comparison operation

+
hamming_matcher

Hamming feature matcher

+
handle_error_general

Default error handling callback provided by ArrayFire crate

+
harris

Harris corner detector.

+
hist_equal

Histogram Equalization

+
histogram

Compute Histogram of an Array

+
homography

Homography estimation

+
hsv2rgb

HSV to RGB color space conversion

+
hypot

Compute length of hypotenuse of two Arrays

+
identity

Create an identity array with 1's in diagonal

+
ifft

Inverse fast fourier transform for 1d signals

+
ifft2

Inverse fast fourier transform for 2d signals

+
ifft2_inplace

In place 2d dimensional inverse fast fourier transform

+
ifft3

Inverse fast fourier transform for 3d signals

+
ifft3_inplace

In place 3d dimensional inverse fast fourier transform

+
ifft_inplace

In place 1d dimensional inverse fast fourier transform

+
iir

Infinite impulse response filter

+
imag

Extract imaginary values from a complex Array

+
imax

Find maximum value along given dimension and their corresponding indices

+
imax_all

Find maximum and it's index in the whole Array

+
imin

Find minimum value along given dimension and their corresponding indices

+
imin_all

Find minimum and it's index in the whole Array

+
index

Indexes the input Array using seqs Sequences

+
index_gen

Index an Array using any combination of Array's and Sequence's

+
info

Print library meta-info

+
info_string

Return library meta-info as String

+
init

Initialize ArrayFire library

+
inverse

Compute inverse of a matrix

+
inverse_deconv

Inverse deconvolution

+
iota

Create a range of values

+
is_double_available

Check if a device has double support

+
is_eval_manual

Get eval flag value

+
is_half_available

Check if a device has half support

+
is_imageio_available

Function to check if Image I/O is available

+
is_lapack_available

Function to check if lapack support is available

+
isinf

Check if values are infinity

+
isnan

Check if values are NaN

+
iszero

Check if values are zero

+
iterative_deconv

Iterative Deconvolution

+
join

Join two arrays

+
join_many

Join multiple arrays

+
le

Perform less than equals comparison operation

+
lgamma

Compute the logarithm of absolute values of gamma function

+
load_image

Load Image into Array

+
load_image_native

Load Image into Array in it's native type

+
locate

Locate the indices of non-zero elements.

+
log

Compute the natural logarithm

+
log1p

Compute the logarithm of input Array + 1

+
log2

Compute logarithm base 2

+
log10

Compute logarithm base 10

+
lookup

Lookup(hash) an Array using another Array

+
lower

Create lower triangular matrix

+
lt

Perform less than comparison operation

+
lu

Perform LU decomposition

+
lu_inplace

Perform inplace LU decomposition

+
match_template

Image matching

+
matmul

Matrix multiple of two Arrays

+
max

Find maximum among elements of given dimension

+
max_all

Find maximum among all values of the Array

+
max_by_key

Find maximum among values of similar keys along a given dimension

+
max_ragged

Max reduction along given axis as per ragged lengths provided

+
maxfilt

Box filter with maximum as box operation

+
maxof

Elementwise maximum operation of two Arrays

+
mean

Mean along specified dimension

+
mean_all

Compute mean of all data

+
mean_all_weighted

Compute weighted mean of all data

+
mean_shift

Meanshift Filter.

+
mean_weighted

Weighted mean along specified dimension

+
meanvar

Calculate mean and variance in single API call

+
medfilt

Median filter

+
medfilt1

One dimensional median filter on image

+
median

Find the median along a given dimension

+
median_all

Compute median of all data

+
min

Find minimum among elements of given dimension

+
min_all

Find minimum among all values of the Array

+
min_by_key

Find minimum among values of similar keys along a given dimension

+
minfilt

Box filter with minimum as box operation

+
minof

Elementwise minimum operation of two Arrays

+
moddims

Change the shape of the Array

+
modulo

Compute modulo of two Arrays

+
moments

Find Image moments

+
moments_all

Find Image moment for whole image

+
mul

Multiplication of two Arrays

+
nearest_neighbour

Nearest Neighbour.

+
neq

Elementwise not equals comparison of two Arrays

+
norm

Find the norm of a matrix

+
or

Elementwise logical or operation of two Arrays

+
orb

ORB feature descriptor

+
pad

Pad input Array along borders

+
pinverse

Psuedo Inverse of Matrix

+
pow

Computer power

+
pow2

Compute two raised to the power of value

+
print

Print data in the Array

+
print_gen

Generalized Array print function

+
print_mem_info

Print buffer details from the ArrayFire device manager

+
product

Compute product of elements along a given dimension

+
product_all

Product of all values of the Array

+
product_by_key

Find product of all values with similar keys along a given dimension

+
product_by_key_nan

Compute product of all values with similar keys along a given dimension

+
product_nan

Product of elements along specific dimension using user specified value instead of NAN values

+
product_nan_all

Product of all values using user provided value for NAN

+
qr

Perform QR decomposition

+
qr_inplace

Perform inplace QR decomposition

+
randn

Create random numbers from normal distribution

+
random_normal

Generate array of normal numbers using a random engine

+
random_uniform

Generate array of uniform numbers using a random engine

+
randu

Create random numbers from uniform distribution

+
range

Create a Range of values

+
rank

Find rank of a matrix

+
real

Extract real values from a complex Array

+
regions

Find blobs in given image.

+
register_error_handler

Register user provided error handler

+
rem

Compute remainder from two Arrays

+
reorderDeprecated

Reorder the array in specified order

+
reorder_v2

Reorder the array according to the new specified axes

+
replace

Inplace replace in Array based on a condition

+
replace_scalar

Inplace replace in Array based on a condition

+
resize

Resize an Image

+
rgb2gray

Color(RGB) to Grayscale conversion

+
rgb2hsv

RGB to HSV color space conversion

+
rgb2ycbcr

RGB to YCbCr colorspace converter.

+
root

Compute root

+
rotate

Rotate an Image

+
round

Round the values in an Array

+
row

Extract row_num row from input Array

+
rows

Get an Array with all rows from first to last in the input Array

+
rsqrt

Compute the reciprocal square root

+
sat

Summed area table of an Image

+
save_image

Save an Array to an image file

+
save_image_native

Save an Array without modifications to an image file

+
scale

Scale an Image

+
scan

Generalized scan

+
scan_by_key

Generalized scan by key

+
select

Element wise conditional operator for Arrays

+
selectl

Element wise conditional operator for Arrays

+
selectr

Element wise conditional operator for Arrays

+
set_backend

Toggle backends between cuda, opencl or cpu

+
set_col

Set col_num^th col in inout Array to a new Array new_col

+
set_cols

Set cols from first to last in inout Array with cols from Array new_cols

+
set_cublas_mode

Sets the cuBLAS math mode for the internal handle.

+
set_default_random_engine_type

Set the random engine type for default random number generator

+
set_device

Set active device

+
set_fft_plan_cache_size

Set fft plan cache size

+
set_intersect

Find intersection of two sets

+
set_manual_eval

Set eval flag value

+
set_mem_step_size

Set the minimum memory chunk size

+
set_row

Set row_num^th row in inout Array to a new Array new_row

+
set_rows

Set rows from first to last in inout Array with rows from Array new_rows

+
set_seed

Set seed for random number generation

+
set_slice

Set slice slice_num in inout Array to a new Array new_slice

+
set_slices

Set first to last slices of inout Array to a new Array new_slices

+
set_union

Find union of two sets

+
set_unique

Find unique values from a Set

+
shift

"Circular shift of values along specified dimension

+
shiftl

Compute left shift

+
shiftr

Compute right shift

+
sigmoid

Compute sigmoid function

+
sign

Computes the sign of input Array values

+
sin

Compute sin

+
sinh

Compute sinh

+
skew

Skew an image

+
slice

Get slice_num^th slice from input Array

+
slices

Get slices from first to last in input Array

+
sobel

Sobel Operator

+
solve

Solve a system of equations

+
solve_lu

Solve a system of equations

+
sort

Sort the values in input Arrays

+
sort_by_key

Sort the values in input Arrays

+
sort_index

Sort the values in input Arrays

+
sparse

Create sprase matrix from arrays

+
sparse_convert_to

Convert between sparse formats

+
sparse_from_dense

Convert dense array to sparse array

+
sparse_from_host

Create sprase matrix from data on host memory

+
sparse_get_col_indices

Get cololumn indices Array

+
sparse_get_format

Get sparse format

+
sparse_get_info

Get sparse Array information

+
sparse_get_nnz

Get number of non-zero elements in sparse array

+
sparse_get_row_indices

Get row indices Array

+
sparse_get_values

Get values of sparse Array

+
sparse_to_dense

Convert sparse array to dense array

+
sqrt

Compute the square root

+
stdevDeprecated

Standard deviation along specified axis

+
stdev_all

Compute standard deviation of all data

+
stdev_all_v2

Compute standard deviation of all data

+
stdev_v2

Standard deviation along given axis

+
sub

Subtraction of two Arrays

+
sum

Sum elements along a given dimension

+
sum_all

Sum all values of the Array

+
sum_by_key

Find sum of all values with similar keys along a given dimension

+
sum_by_key_nan

Compute sum of all values with similar keys along a given dimension

+
sum_nan

Sum along specific dimension using user specified value instead of NAN values

+
sum_nan_all

Sum all values using user provided value for NAN

+
susan

SUSAN corner detector.

+
svd

Perform Singular Value Decomposition

+
svd_inplace

Perform Singular Value Decomposition inplace

+
sync

Sync all operations on given device

+
tan

Compute tan

+
tanh

Compute tanh

+
tgamma

Compute gamma function

+
tile

Tile the input array along specified dimension

+
topk

Find top k elements along a given dimension

+
transform

Transform(Affine) an Image

+
transform_coords

Transform input coordinates

+
translate

Translate an Image

+
transpose

Transpose of a matrix.

+
transpose_inplace

Inplace transpose of a matrix.

+
trunc

Truncate the values in an Array

+
unwrap

Generate an array with image windows as columns

+
upper

Create upper triangular matrix

+
varDeprecated

Compute Variance along a specific dimension

+
var_allDeprecated

Compute Variance of all elements

+
var_all_v2

Compute Variance of all elements

+
var_all_weighted

Compute weighted variance of all data

+
var_v2

Compute Variance along a specific dimension

+
var_weighted

Weight variance along specified dimension

+
wrap

Converts unwrapped image to an image

+
ycbcr2rgb

YCbCr to RGB colorspace converter.

+

Type Definitions

+
ErrorCallback

Signature of error handling callback function

+
af_array

ArrayFire FFI Type alias for af_array

+
af_event

ArrayFire FFI Type alias for af_event

+
af_features

ArrayFire FFI Type alias for af_features

+
af_index_t

ArrayFire FFI Type alias for af_indexers_t

+
af_random_engine

ArrayFire FFI Type alias for af_random_engine

+
af_window

ArrayFire FFI Type alias for af_window

+
c32

Short type alias for Complex single precision type

+
c64

Short type alias for Complex double precision type

+
dim_t

ArrayFire FFI Type alias for libc's signed long long

+
u64_t

ArrayFire FFI Type alias for libc's unsigned long long

+
void_ptr

ArrayFire FFI Type alias for libc's void*

+
\ No newline at end of file diff --git a/arrayfire/lapack/fn.cholesky.html b/arrayfire/lapack/fn.cholesky.html new file mode 100644 index 000000000..f54579259 --- /dev/null +++ b/arrayfire/lapack/fn.cholesky.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.cholesky.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.cholesky_inplace.html b/arrayfire/lapack/fn.cholesky_inplace.html new file mode 100644 index 000000000..7ee3448f6 --- /dev/null +++ b/arrayfire/lapack/fn.cholesky_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.cholesky_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.det.html b/arrayfire/lapack/fn.det.html new file mode 100644 index 000000000..a82a395ff --- /dev/null +++ b/arrayfire/lapack/fn.det.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.det.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.inverse.html b/arrayfire/lapack/fn.inverse.html new file mode 100644 index 000000000..7f2abc992 --- /dev/null +++ b/arrayfire/lapack/fn.inverse.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.inverse.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.is_lapack_available.html b/arrayfire/lapack/fn.is_lapack_available.html new file mode 100644 index 000000000..eb66b0365 --- /dev/null +++ b/arrayfire/lapack/fn.is_lapack_available.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.is_lapack_available.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.lu.html b/arrayfire/lapack/fn.lu.html new file mode 100644 index 000000000..ff9ecdeb0 --- /dev/null +++ b/arrayfire/lapack/fn.lu.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.lu.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.lu_inplace.html b/arrayfire/lapack/fn.lu_inplace.html new file mode 100644 index 000000000..730100058 --- /dev/null +++ b/arrayfire/lapack/fn.lu_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.lu_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.norm.html b/arrayfire/lapack/fn.norm.html new file mode 100644 index 000000000..b2b46f0a2 --- /dev/null +++ b/arrayfire/lapack/fn.norm.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.norm.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.pinverse.html b/arrayfire/lapack/fn.pinverse.html new file mode 100644 index 000000000..ca125f5b6 --- /dev/null +++ b/arrayfire/lapack/fn.pinverse.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.pinverse.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.qr.html b/arrayfire/lapack/fn.qr.html new file mode 100644 index 000000000..dd77dc278 --- /dev/null +++ b/arrayfire/lapack/fn.qr.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.qr.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.qr_inplace.html b/arrayfire/lapack/fn.qr_inplace.html new file mode 100644 index 000000000..21abd8e8c --- /dev/null +++ b/arrayfire/lapack/fn.qr_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.qr_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.rank.html b/arrayfire/lapack/fn.rank.html new file mode 100644 index 000000000..fff9146d7 --- /dev/null +++ b/arrayfire/lapack/fn.rank.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.rank.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.solve.html b/arrayfire/lapack/fn.solve.html new file mode 100644 index 000000000..ba8e9570c --- /dev/null +++ b/arrayfire/lapack/fn.solve.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.solve.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.solve_lu.html b/arrayfire/lapack/fn.solve_lu.html new file mode 100644 index 000000000..c42464e69 --- /dev/null +++ b/arrayfire/lapack/fn.solve_lu.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.solve_lu.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.svd.html b/arrayfire/lapack/fn.svd.html new file mode 100644 index 000000000..1b2b8ff97 --- /dev/null +++ b/arrayfire/lapack/fn.svd.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.svd.html...

+ + + \ No newline at end of file diff --git a/arrayfire/lapack/fn.svd_inplace.html b/arrayfire/lapack/fn.svd_inplace.html new file mode 100644 index 000000000..8a145e2a0 --- /dev/null +++ b/arrayfire/lapack/fn.svd_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.svd_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.af_print!.html b/arrayfire/macro.af_print!.html new file mode 100644 index 000000000..26944da01 --- /dev/null +++ b/arrayfire/macro.af_print!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.af_print.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.af_print.html b/arrayfire/macro.af_print.html new file mode 100644 index 000000000..96263b933 --- /dev/null +++ b/arrayfire/macro.af_print.html @@ -0,0 +1,26 @@ +arrayfire::af_print - Rust + + + +

[][src]Macro arrayfire::af_print

+macro_rules! af_print {
+    [$msg: expr, $x: expr] => { ... };
+}
+

Print given message before printing out the Array to standard output

+

Examples

+
+use arrayfire::{Dim4, print_gen, randu, af_print};
+let dims = Dim4::new(&[3, 1, 1, 1]);
+let a = randu::<f32>(dims);
+af_print!("Create a 5-by-3 matrix of random floats on the GPU", a);
+
\ No newline at end of file diff --git a/arrayfire/macro.constant!.html b/arrayfire/macro.constant!.html new file mode 100644 index 000000000..3d6ef432b --- /dev/null +++ b/arrayfire/macro.constant!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.constant.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.constant.html b/arrayfire/macro.constant.html new file mode 100644 index 000000000..067b1735a --- /dev/null +++ b/arrayfire/macro.constant.html @@ -0,0 +1,27 @@ +arrayfire::constant - Rust + + + +

[][src]Macro arrayfire::constant

+macro_rules! constant {
+    ($value:expr; $($dim:expr),+) => { ... };
+}
+

Create an array of given shape filled with a single value a.k.a constant array

+

Examples

+
+let _zeros_1d = constant!(0.0f32; 10);
+let _ones_3d = constant!(1u32; 3, 3, 3);
+
+let dim = 10;
+let mix_shape = constant!(42.0f32; dim, 10);
+
\ No newline at end of file diff --git a/arrayfire/macro.dim4!.html b/arrayfire/macro.dim4!.html new file mode 100644 index 000000000..31aeccae9 --- /dev/null +++ b/arrayfire/macro.dim4!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.dim4.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.dim4.html b/arrayfire/macro.dim4.html new file mode 100644 index 000000000..604c042e1 --- /dev/null +++ b/arrayfire/macro.dim4.html @@ -0,0 +1,24 @@ +arrayfire::dim4 - Rust + + + +

[][src]Macro arrayfire::dim4

+macro_rules! dim4 {
+    ($dim0:expr) => { ... };
+    ($dim0:expr, $dim1:expr) => { ... };
+    ($dim0:expr, $dim1:expr, $dim2:expr) => { ... };
+    ($dim0:expr, $dim1:expr, $dim2:expr, $dim3:expr) => { ... };
+}
+

Create a dim4 object from provided dimensions

+

The user can pass 1 or more sizes and the left over values will default to 1.

+
\ No newline at end of file diff --git a/arrayfire/macro.eval!.html b/arrayfire/macro.eval!.html new file mode 100644 index 000000000..1ae15fd04 --- /dev/null +++ b/arrayfire/macro.eval!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.eval.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.eval.html b/arrayfire/macro.eval.html new file mode 100644 index 000000000..5565f6fb4 --- /dev/null +++ b/arrayfire/macro.eval.html @@ -0,0 +1,47 @@ +arrayfire::eval - Rust + + + +

[][src]Macro arrayfire::eval

+macro_rules! eval {
+    ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] =
+      $r:ident [ $($rb:literal : $re:literal : $rs:literal),+ ]) => { ... };
+    ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] = $r:expr ) => { ... };
+    ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:ident [ $($rhs_e:expr),+ ]) => { ... };
+    ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:expr) => { ... };
+    [$($x:expr),+] => { ... };
+}
+

Macro to evaluate individual Arrays or assignment operations

+
    +
  • +

    Evaluate on one or more Array identifiers: essentially calls Array::eval on each of those +Array objects individually.

    + +
    +use arrayfire::{dim4, eval, randu};
    +let dims = dim4!(5, 5);
    +let a = randu::<f32>(dims);
    +let b = a.clone();
    +let c = a.clone();
    +let d = a.clone();
    +let x = a - b;
    +let y = c * d;
    +eval!(&x, &y);
    +
  • +
  • +

    Evaluate assignment operations: This is essentially syntactic sugar for modifying portions of +Array with another Array using a combination of Sequences and/or Array objects. +Full examples for this use case are provided in the tutorials book

    +
  • +
+
\ No newline at end of file diff --git a/arrayfire/macro.join_many!.html b/arrayfire/macro.join_many!.html new file mode 100644 index 000000000..490d86ad2 --- /dev/null +++ b/arrayfire/macro.join_many!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.join_many.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.join_many.html b/arrayfire/macro.join_many.html new file mode 100644 index 000000000..6f02a1c97 --- /dev/null +++ b/arrayfire/macro.join_many.html @@ -0,0 +1,33 @@ +arrayfire::join_many - Rust + + + +

[][src]Macro arrayfire::join_many

+macro_rules! join_many {
+    [$dim: expr; $($x:expr),+] => { ... };
+}
+

Join multiple Arrays along a given dimension

+

All the Arrays provided to this macro should be of type &Array

+

Examples

+
+use arrayfire::{Dim4, join_many, print, randu};
+
+let a = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+let b = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+let c = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+let d = join_many![2; a, b, c];
+print(&d);
+

Panics

+

This macro just calls join_many function after collecting all +the input arrays into a vector.

+
\ No newline at end of file diff --git a/arrayfire/macro.mem_info!.html b/arrayfire/macro.mem_info!.html new file mode 100644 index 000000000..34aa07540 --- /dev/null +++ b/arrayfire/macro.mem_info!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.mem_info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.mem_info.html b/arrayfire/macro.mem_info.html new file mode 100644 index 000000000..99b267dae --- /dev/null +++ b/arrayfire/macro.mem_info.html @@ -0,0 +1,60 @@ +arrayfire::mem_info - Rust + + + +

[][src]Macro arrayfire::mem_info

+macro_rules! mem_info {
+    [$msg: expr] => { ... };
+}
+

Macro to print the current stats of ArrayFire's memory manager.

+

mem_info! print 4 values:

+ + + + + +
NameDescription
Allocated BytesTotal number of bytes allocated by the memory manager
Allocated BuffersTotal number of buffers allocated
Locked (In Use) BytesNumber of bytes that are in use by active arrays
Locked (In Use) BuffersNumber of buffers that are in use by active arrays
+

The Allocated Bytes is always a multiple of the memory step size. The +default step size is 1024 bytes. This means when a buffer is to be +allocated, the size is always rounded up to a multiple of the step size. +You can use get_mem_step_size to check the +current step size and set_mem_step_size to +set a custom resolution size.

+

The Allocated Buffers is the number of buffers that use up the allocated +bytes. This includes buffers currently in scope, as well as buffers marked +as free, ie, from arrays gone out of scope. The free buffers are available +for use by new arrays that might be created.

+

The Locked Bytes is the number of bytes in use that cannot be +reallocated at the moment. The difference of Allocated Bytes and Locked +Bytes is the total bytes available for reallocation.

+

The Locked Buffers is the number of buffer in use that cannot be +reallocated at the moment. The difference of Allocated Buffers and Locked +Buffers is the number of buffers available for reallocation.

+

Parameters

+
    +
  • msg is the message that is printed to screen before printing stats
  • +
+

Examples

+
+use arrayfire::{Dim4, device_mem_info, print, randu, mem_info};
+
+let dims = Dim4::new(&[5, 5, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+mem_info!("Hello!");
+

Sample Output:

+
AF Memory: Here
+Allocated [ Bytes | Buffers ] = [ 4096 | 4 ]
+In Use    [ Bytes | Buffers ] = [ 2048 | 2 ]
+
+
\ No newline at end of file diff --git a/arrayfire/macro.randn!.html b/arrayfire/macro.randn!.html new file mode 100644 index 000000000..c0ddaa5a0 --- /dev/null +++ b/arrayfire/macro.randn!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.randn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.randn.html b/arrayfire/macro.randn.html new file mode 100644 index 000000000..e8ca5ca66 --- /dev/null +++ b/arrayfire/macro.randn.html @@ -0,0 +1,25 @@ +arrayfire::randn - Rust + + + +

[][src]Macro arrayfire::randn

+macro_rules! randn {
+    ($($dim:expr),+) => { ... };
+    ($type:ty; $($dim:expr),+) => { ... };
+}
+

Create an array of given shape sampled from normal distribution

+

If no type argument is specified, the data type defaults to 32 bit floats.

+

Examples

+
+let mat10x10 = randn!(10, 10);
+
\ No newline at end of file diff --git a/arrayfire/macro.randu!.html b/arrayfire/macro.randu!.html new file mode 100644 index 000000000..0c43f802b --- /dev/null +++ b/arrayfire/macro.randu!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.randu.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.randu.html b/arrayfire/macro.randu.html new file mode 100644 index 000000000..f02fad03e --- /dev/null +++ b/arrayfire/macro.randu.html @@ -0,0 +1,25 @@ +arrayfire::randu - Rust + + + +

[][src]Macro arrayfire::randu

+macro_rules! randu {
+    ($($dim:expr),+) => { ... };
+    ($type:ty; $($dim:expr),+) => { ... };
+}
+

Create an array of given shape sampled from uniform distribution

+

If no type argument is specified, the data type defaults to 32 bit floats.

+

Examples

+
+let mat10x10 = randu!(10, 10);
+
\ No newline at end of file diff --git a/arrayfire/macro.seq!.html b/arrayfire/macro.seq!.html new file mode 100644 index 000000000..8d475de76 --- /dev/null +++ b/arrayfire/macro.seq!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.seq.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.seq.html b/arrayfire/macro.seq.html new file mode 100644 index 000000000..5ef39a2d9 --- /dev/null +++ b/arrayfire/macro.seq.html @@ -0,0 +1,25 @@ +arrayfire::seq - Rust + + + +

[][src]Macro arrayfire::seq

+macro_rules! seq {
+    () => { ... };
+    ($sty:ty; $start:literal : $end:literal : $step:literal) => { ... };
+    ($start:literal : $end:literal : $step:literal) => { ... };
+    ($sty:ty; $start:expr , $end:expr , $step:expr) => { ... };
+    ($start:expr , $end:expr , $step:expr) => { ... };
+}
+

Create a sequence object

+

If type is not provided, then the Seq will default to i32 type

+
\ No newline at end of file diff --git a/arrayfire/macro.view!.html b/arrayfire/macro.view!.html new file mode 100644 index 000000000..865dee217 --- /dev/null +++ b/arrayfire/macro.view!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.view.html...

+ + + \ No newline at end of file diff --git a/arrayfire/macro.view.html b/arrayfire/macro.view.html new file mode 100644 index 000000000..d57cd24cf --- /dev/null +++ b/arrayfire/macro.view.html @@ -0,0 +1,36 @@ +arrayfire::view - Rust + + + +

[][src]Macro arrayfire::view

+macro_rules! view {
+    (@af_max_dims) => { ... };
+    ( $array_ident:ident ) => { ... };
+    ( $array_ident:ident [ $($start:literal : $end:literal : $step:literal),+ ] ) => { ... };
+    (@set_indexer $idim:expr, $idxr:ident, $lterm:expr) => { ... };
+    (@set_indexer $idim:expr, $idxr:ident, $hterm:expr, $($tterm:expr),*) => { ... };
+    ($array_ident:ident [ $($_e:expr),+ ]) => { ... };
+}
+

Indexing into an existing Array

+

This macro call with return an Array that has a view of another Array. The Array returned due to +the indexing operation will follow copy-on-write semantics. The Array identifier taken by this +macro is passed to the relevant internal functions as a borrowed reference. Thus, this identifier +will be still available for futher use after the macro call.

+

The following types of inputs are matched by this macro.

+
    +
  • A simple Array identifier.
  • +
  • An Array with slicing info for indexing.
  • +
  • An Array with slicing info and other arrays used for indexing.
  • +
+

Examples on how to use this macro are provided in the tutorials book

+
\ No newline at end of file diff --git a/arrayfire/ml/fn.convolve2_gradient_nn.html b/arrayfire/ml/fn.convolve2_gradient_nn.html new file mode 100644 index 000000000..5c87e3c25 --- /dev/null +++ b/arrayfire/ml/fn.convolve2_gradient_nn.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve2_gradient_nn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/ml/fn.convolve2_nn.html b/arrayfire/ml/fn.convolve2_nn.html new file mode 100644 index 000000000..d20f44063 --- /dev/null +++ b/arrayfire/ml/fn.convolve2_nn.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve2_nn.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sidebar-items.js b/arrayfire/sidebar-items.js new file mode 100644 index 000000000..05bfccdbf --- /dev/null +++ b/arrayfire/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"constant":[["DEFAULT_RANDOM_ENGINE","Default RandomEngine that defaults to PHILOX"],["MERSENNE","Default Mersenne RandomEngine that points to MERSENNE_GP11213"],["PHILOX","Default Philon RandomEngine that points to PHILOX_4X32_10"],["THREEFRY","Default Threefry RandomEngine that points to THREEFRY_2X32_16"]],"enum":[["AfError","Error codes"],["Backend","Compute/Acceleration Backend"],["BinaryOp","Binary operation types for generalized scan functions"],["BorderType","Helps determine how to pad kernels along borders"],["CannyThresholdType","Canny edge detector threshold operations types"],["ColorMap","Dictates what color map is used for Image rendering"],["ColorSpace","Identify the color space of given image(Array)"],["Connectivity","Used by `regions` function to identify type of connectivity"],["ConvDomain","Helps determine if convolution is in Spatial or Frequency domain"],["ConvGradientType","Gradient mode for convolution"],["ConvMode","Helps determine the size of output of convolution"],["CublasMathMode","Gradient mode for convolution"],["DType","Types of Array data type"],["DiffusionEq","Anisotropic diffusion flux equation types"],["FluxFn","Diffusion equation types"],["HomographyType","Homography type"],["InterpType","Dictates the interpolation method to be used by a function"],["InverseDeconvAlgo","Inverse Deconvolution Algorithm"],["IterativeDeconvAlgo","Iterative Deconvolution Algorithm"],["MarkerType","Plotting markers"],["MatProp","Helps determine the type of a Matrix"],["MatchType","Error metric used by `matchTemplate` function"],["MomentType","Image moment types"],["NormType","Norm type"],["RandomEngineType","Random engine types"],["Scalar","Scalar value types"],["SparseFormat","Sparse storage format type"],["TopkFn","topk function ordering"],["VarianceBias","Gradient mode for convolution"],["YCCStd","YCbCr Standards"]],"fn":[["HANDLE_ERROR","Default error handler for error code returned by ArrayFire FFI calls"],["abs","Computes absolute value"],["accum","Perform exclusive sum of elements along a given dimension"],["acos","Compute acos"],["acosh","Compute acosh"],["add","Addition of two Arrays"],["all_true","Find if all of the values along a given dimension in the Array are true"],["all_true_all","Find if all values of Array are non-zero"],["all_true_by_key","Key based AND of elements along a given dimension"],["alloc_host","Allocates space using Arrayfire allocator in host memory"],["alloc_pinned","Allocate non-pageable memory on HOST memory"],["and","Elementwise logical and operation of two Arrays"],["anisotropic_diffusion","Anisotropic smoothing filter"],["any_true","Find if any of the values along a given dimension in the Array are true"],["any_true_all","Find if any value of Array is non-zero"],["any_true_by_key","Key based OR of elements along a given dimension"],["approx1","Perform signal interpolation for 1d signals"],["approx1_uniform","Perform signal interpolation for 1d signals along specified dimension"],["approx1_uniform_v2","Same as approx1_uniform but uses existing Array as output"],["approx1_v2","Same as approx1 but uses existing Array as output"],["approx2","Perform signal interpolation for 2d signals"],["approx2_uniform","Perform signal interpolation for 2d signals along a specified dimension"],["approx2_uniform_v2","Same as approx2_uniform but uses existing Array as output"],["approx2_v2","Same as approx2 but uses existing Array as output"],["arg","Computes phase value"],["asin","Compute asin"],["asinh","Compute asinh"],["assign_gen","Assign an Array to another after indexing it using any combination of Array's and Sequence's"],["assign_seq","Assign(copy) content of an Array to another Array indexed by Sequences"],["atan","Compute atan"],["atan2","Calculate atan2 of two Arrays"],["atanh","Compute atanh"],["bilateral","Bilateral Filter."],["bitand","Elementwise AND(bit) operation of two Arrays"],["bitnot","Perform bitwise complement on all values of Array"],["bitor","Elementwise OR(bit) operation of two Arrays"],["bitxor","Elementwise XOR(bit) operation of two Arrays"],["canny","Canny edge detection operator"],["cbrt","Compute the cube root"],["ceil","Ceil the values in an Array"],["cholesky","Perform Cholesky decomposition"],["cholesky_inplace","Perform inplace Cholesky decomposition"],["clamp","Clamp the values of Array"],["col","Extract `col_num` col from `input` Array"],["color_space","Color space conversion"],["cols","Get all cols from `first` to `last` in the `input` Array"],["confidence_cc","Segment image based on similar pixel characteristics"],["conjg","Compute the complex conjugate"],["constant","Create an Array with constant value"],["convolve1","1d convolution"],["convolve2","2d convolution"],["convolve2_gradient_nn","Backward pass gradient of 2D convolution"],["convolve2_nn","Convolution Integral for two dimensional data"],["convolve2_sep","Separable convolution for 2d signals"],["convolve3","3d convolution"],["corrcoef","Compute correlation coefficient"],["cos","Compute cos"],["cosh","Compute cosh"],["count","Count number of non-zero elements along a given dimension"],["count_all","Count number of non-zero values in the Array"],["count_by_key","Find total count of elements with similar keys along a given dimension"],["cov","Compute covariance of two Arrays"],["cov_v2","Compute covariance of two Arrays"],["cplx","Create a complex Array from real Array"],["cplx2","Create complex array from two Arrays"],["det","Find the determinant of the matrix"],["device_count","Get total number of available devices"],["device_gc","Call the garbage collection routine"],["device_info","Gets the information about device and platform as strings."],["device_mem_info","Get memory information from the memory manager for the current active device"],["diag_create","Create a diagonal matrix"],["diag_extract","Extract diagonal from a given Matrix"],["diff1","Calculate first order numerical difference along a given dimension"],["diff2","Calculate second order numerical difference along a given dimension"],["dilate","Dilate an Image"],["dilate3","Dilate a Volume"],["div","Division of two Arrays"],["dog","Difference of Gaussians."],["dot","Calculate the dot product of vectors."],["eq","Perform `equals` comparison operation"],["erf","Compute error function value"],["erfc","Compute the complementary error function value"],["erode","Erode an Image"],["erode3","Erode a Volume"],["eval_multiple","evaluate multiple arrays"],["exp","Compute e raised to the power of value"],["expm1","Compute e raised to the power of value -1"],["factorial","Compute the factorial"],["fast","Fast feature detector"],["fft","Fast fourier transform for 1d signals"],["fft2","Fast fourier transform for 2d signals"],["fft2_c2r","2d Complex to Real fast fourier transform"],["fft2_inplace","In place 2d dimensional Fast fourier transform"],["fft2_r2c","2d Real to Complex fast fourier transform"],["fft3","Fast fourier transform for 3d signals"],["fft3_c2r","3d Complex to Real fast fourier transform"],["fft3_inplace","In place 3d dimensional Fast fourier transform"],["fft3_r2c","3d Real to Complex fast fourier transform"],["fft_c2r","1d Complex to Real fast fourier transform"],["fft_convolve1","1d convolution using fast-fourier transform"],["fft_convolve2","2d convolution using fast-fourier transform"],["fft_convolve3","3d convolution using fast-fourier transform"],["fft_inplace","In place 1d dimensional Fast fourier transform"],["fft_r2c","1d Real to Complex fast fourier transform"],["fir","Finite impulse filter"],["flat","Flatten the multidimensional Array to an 1D Array"],["flip","Flip the Array"],["floor","Floor the values in an Array"],["free_host","Frees memory allocated by Arrayfire allocator in host memory"],["free_pinned","Free the pointer returned by alloc_pinned"],["gaussian_kernel","Creates a Gaussian Kernel."],["ge","Perform `greater than equals` comparison operation"],["gemm","BLAS general matrix multiply (GEMM) of two Array objects"],["get_active_backend","Get current active backend"],["get_available_backends","Get the available backends"],["get_backend_count","Get the available backend count"],["get_default_random_engine","Get default random engine"],["get_device","Get the current active device id"],["get_last_error","Fetch last error description as String"],["get_mem_step_size","Get the minimum memory chunk size"],["get_revision","Get ArrayFire Revision (commit) information of the library."],["get_seed","Get the seed of random number generator"],["get_size","Get size, in bytes, of the arrayfire native type"],["get_version","Get ArrayFire Version Number"],["gradient","Calculate the gradients"],["gray2rgb","Grayscale to Color(RGB) conversion"],["gt","Perform `greater than` comparison operation"],["hamming_matcher","Hamming feature matcher"],["handle_error_general","Default error handling callback provided by ArrayFire crate"],["harris","Harris corner detector."],["hist_equal","Histogram Equalization"],["histogram","Compute Histogram of an Array"],["homography","Homography estimation"],["hsv2rgb","HSV to RGB color space conversion"],["hypot","Compute length of hypotenuse of two Arrays"],["identity","Create an identity array with 1's in diagonal"],["ifft","Inverse fast fourier transform for 1d signals"],["ifft2","Inverse fast fourier transform for 2d signals"],["ifft2_inplace","In place 2d dimensional inverse fast fourier transform"],["ifft3","Inverse fast fourier transform for 3d signals"],["ifft3_inplace","In place 3d dimensional inverse fast fourier transform"],["ifft_inplace","In place 1d dimensional inverse fast fourier transform"],["iir","Infinite impulse response filter"],["imag","Extract imaginary values from a complex Array"],["imax","Find maximum value along given dimension and their corresponding indices"],["imax_all","Find maximum and it's index in the whole Array"],["imin","Find minimum value along given dimension and their corresponding indices"],["imin_all","Find minimum and it's index in the whole Array"],["index","Indexes the `input` Array using `seqs` Sequences"],["index_gen","Index an Array using any combination of Array's and Sequence's"],["info","Print library meta-info"],["info_string","Return library meta-info as `String`"],["init","Initialize ArrayFire library"],["inverse","Compute inverse of a matrix"],["inverse_deconv","Inverse deconvolution"],["iota","Create a range of values"],["is_double_available","Check if a device has double support"],["is_eval_manual","Get eval flag value"],["is_half_available","Check if a device has half support"],["is_imageio_available","Function to check if Image I/O is available"],["is_lapack_available","Function to check if lapack support is available"],["isinf","Check if values are infinity"],["isnan","Check if values are NaN"],["iszero","Check if values are zero"],["iterative_deconv","Iterative Deconvolution"],["join","Join two arrays"],["join_many","Join multiple arrays"],["le","Perform `less than equals` comparison operation"],["lgamma","Compute the logarithm of absolute values of gamma function"],["load_image","Load Image into Array"],["load_image_native","Load Image into Array in it's native type"],["locate","Locate the indices of non-zero elements."],["log","Compute the natural logarithm"],["log10","Compute logarithm base 10"],["log1p","Compute the logarithm of input Array + 1"],["log2","Compute logarithm base 2"],["lookup","Lookup(hash) an Array using another Array"],["lower","Create lower triangular matrix"],["lt","Perform `less than` comparison operation"],["lu","Perform LU decomposition"],["lu_inplace","Perform inplace LU decomposition"],["match_template","Image matching"],["matmul","Matrix multiple of two Arrays"],["max","Find maximum among elements of given dimension"],["max_all","Find maximum among all values of the Array"],["max_by_key","Find maximum among values of similar keys along a given dimension"],["max_ragged","Max reduction along given axis as per ragged lengths provided"],["maxfilt","Box filter with maximum as box operation"],["maxof","Elementwise maximum operation of two Arrays"],["mean","Mean along specified dimension"],["mean_all","Compute mean of all data"],["mean_all_weighted","Compute weighted mean of all data"],["mean_shift","Meanshift Filter."],["mean_weighted","Weighted mean along specified dimension"],["meanvar","Calculate mean and variance in single API call"],["medfilt","Median filter"],["medfilt1","One dimensional median filter on image"],["median","Find the median along a given dimension"],["median_all","Compute median of all data"],["min","Find minimum among elements of given dimension"],["min_all","Find minimum among all values of the Array"],["min_by_key","Find minimum among values of similar keys along a given dimension"],["minfilt","Box filter with minimum as box operation"],["minof","Elementwise minimum operation of two Arrays"],["moddims","Change the shape of the Array"],["modulo","Compute modulo of two Arrays"],["moments","Find Image moments"],["moments_all","Find Image moment for whole image"],["mul","Multiplication of two Arrays"],["nearest_neighbour","Nearest Neighbour."],["neq","Elementwise not equals comparison of two Arrays"],["norm","Find the norm of a matrix"],["or","Elementwise logical or operation of two Arrays"],["orb","ORB feature descriptor"],["pad","Pad input Array along borders"],["pinverse","Psuedo Inverse of Matrix"],["pow","Computer power"],["pow2","Compute two raised to the power of value"],["print","Print data in the Array"],["print_gen","Generalized Array print function"],["print_mem_info","Print buffer details from the ArrayFire device manager"],["product","Compute product of elements along a given dimension"],["product_all","Product of all values of the Array"],["product_by_key","Find product of all values with similar keys along a given dimension"],["product_by_key_nan","Compute product of all values with similar keys along a given dimension"],["product_nan","Product of elements along specific dimension using user specified value instead of `NAN` values"],["product_nan_all","Product of all values using user provided value for `NAN`"],["qr","Perform QR decomposition"],["qr_inplace","Perform inplace QR decomposition"],["randn","Create random numbers from normal distribution"],["random_normal","Generate array of normal numbers using a random engine"],["random_uniform","Generate array of uniform numbers using a random engine"],["randu","Create random numbers from uniform distribution"],["range","Create a Range of values"],["rank","Find rank of a matrix"],["real","Extract real values from a complex Array"],["regions","Find blobs in given image."],["register_error_handler","Register user provided error handler"],["rem","Compute remainder from two Arrays"],["reorder","Reorder the array in specified order"],["reorder_v2","Reorder the array according to the new specified axes"],["replace","Inplace replace in Array based on a condition"],["replace_scalar","Inplace replace in Array based on a condition"],["resize","Resize an Image"],["rgb2gray","Color(RGB) to Grayscale conversion"],["rgb2hsv","RGB to HSV color space conversion"],["rgb2ycbcr","RGB to YCbCr colorspace converter."],["root","Compute root"],["rotate","Rotate an Image"],["round","Round the values in an Array"],["row","Extract `row_num` row from `input` Array"],["rows","Get an Array with all rows from `first` to `last` in the `input` Array"],["rsqrt","Compute the reciprocal square root"],["sat","Summed area table of an Image"],["save_image","Save an Array to an image file"],["save_image_native","Save an Array without modifications to an image file"],["scale","Scale an Image"],["scan","Generalized scan"],["scan_by_key","Generalized scan by key"],["select","Element wise conditional operator for Arrays"],["selectl","Element wise conditional operator for Arrays"],["selectr","Element wise conditional operator for Arrays"],["set_backend","Toggle backends between cuda, opencl or cpu"],["set_col","Set `col_num`^th col in `inout` Array to a new Array `new_col`"],["set_cols","Set cols from `first` to `last` in `inout` Array with cols from Array `new_cols`"],["set_cublas_mode","Sets the cuBLAS math mode for the internal handle."],["set_default_random_engine_type","Set the random engine type for default random number generator"],["set_device","Set active device"],["set_fft_plan_cache_size","Set fft plan cache size"],["set_intersect","Find intersection of two sets"],["set_manual_eval","Set eval flag value"],["set_mem_step_size","Set the minimum memory chunk size"],["set_row","Set `row_num`^th row in `inout` Array to a new Array `new_row`"],["set_rows","Set rows from `first` to `last` in `inout` Array with rows from Array `new_rows`"],["set_seed","Set seed for random number generation"],["set_slice","Set slice `slice_num` in `inout` Array to a new Array `new_slice`"],["set_slices","Set `first` to `last` slices of `inout` Array to a new Array `new_slices`"],["set_union","Find union of two sets"],["set_unique","Find unique values from a Set"],["shift","\"Circular shift of values along specified dimension"],["shiftl","Compute left shift"],["shiftr","Compute right shift"],["sigmoid","Compute sigmoid function"],["sign","Computes the sign of input Array values"],["sin","Compute sin"],["sinh","Compute sinh"],["skew","Skew an image"],["slice","Get `slice_num`^th slice from `input` Array"],["slices","Get slices from `first` to `last` in `input` Array"],["sobel","Sobel Operator"],["solve","Solve a system of equations"],["solve_lu","Solve a system of equations"],["sort","Sort the values in input Arrays"],["sort_by_key","Sort the values in input Arrays"],["sort_index","Sort the values in input Arrays"],["sparse","Create sprase matrix from arrays"],["sparse_convert_to","Convert between sparse formats"],["sparse_from_dense","Convert dense array to sparse array"],["sparse_from_host","Create sprase matrix from data on host memory"],["sparse_get_col_indices","Get cololumn indices Array"],["sparse_get_format","Get sparse format"],["sparse_get_info","Get sparse Array information"],["sparse_get_nnz","Get number of non-zero elements in sparse array"],["sparse_get_row_indices","Get row indices Array"],["sparse_get_values","Get values of sparse Array"],["sparse_to_dense","Convert sparse array to dense array"],["sqrt","Compute the square root"],["stdev","Standard deviation along specified axis"],["stdev_all","Compute standard deviation of all data"],["stdev_all_v2","Compute standard deviation of all data"],["stdev_v2","Standard deviation along given axis"],["sub","Subtraction of two Arrays"],["sum","Sum elements along a given dimension"],["sum_all","Sum all values of the Array"],["sum_by_key","Find sum of all values with similar keys along a given dimension"],["sum_by_key_nan","Compute sum of all values with similar keys along a given dimension"],["sum_nan","Sum along specific dimension using user specified value instead of `NAN` values"],["sum_nan_all","Sum all values using user provided value for `NAN`"],["susan","SUSAN corner detector."],["svd","Perform Singular Value Decomposition"],["svd_inplace","Perform Singular Value Decomposition inplace"],["sync","Sync all operations on given device"],["tan","Compute tan"],["tanh","Compute tanh"],["tgamma","Compute gamma function"],["tile","Tile the input array along specified dimension"],["topk","Find top k elements along a given dimension"],["transform","Transform(Affine) an Image"],["transform_coords","Transform input coordinates"],["translate","Translate an Image"],["transpose","Transpose of a matrix."],["transpose_inplace","Inplace transpose of a matrix."],["trunc","Truncate the values in an Array"],["unwrap","Generate an array with image windows as columns"],["upper","Create upper triangular matrix"],["var","Compute Variance along a specific dimension"],["var_all","Compute Variance of all elements"],["var_all_v2","Compute Variance of all elements"],["var_all_weighted","Compute weighted variance of all data"],["var_v2","Compute Variance along a specific dimension"],["var_weighted","Weight variance along specified dimension"],["wrap","Converts unwrapped image to an image"],["ycbcr2rgb","YCbCr to RGB colorspace converter."]],"macro":[["af_print","Print given message before printing out the Array to standard output"],["constant","Create an array of given shape filled with a single value a.k.a constant array"],["dim4","Create a dim4 object from provided dimensions"],["eval","Macro to evaluate individual Arrays or assignment operations"],["join_many","Join multiple Arrays along a given dimension"],["mem_info","Macro to print the current stats of ArrayFire's memory manager."],["randn","Create an array of given shape sampled from normal distribution"],["randu","Create an array of given shape sampled from uniform distribution"],["seq","Create a sequence object"],["view","Indexing into an existing Array"]],"struct":[["Array","A multidimensional data container"],["Callback","Structure holding handle to callback function"],["Dim4","Dim4 is used to store Array dimensions"],["Event","RAII construct to manage ArrayFire events"],["Features","A set of Array objects (usually, used in Computer vision context)"],["Indexer","Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct)"],["RandomEngine","Random number generator engine"],["Seq","Sequences are used for indexing Arrays"],["Window","Used to render Array objects"]],"trait":[["ComplexFloating","Trait qualifier to accept complex data(numbers)"],["ConfidenceCCInput","Trait qualifier for confidence connected components input"],["ConstGenerator","Type Trait to generate a constant Array of given size"],["Convertable","Type Trait to convert to an Array"],["CovarianceComputable","Trait qualifier for given type indicating computability of covariance"],["DeconvInput","Trait qualifier for confidence connected components input"],["EdgeComputable","Trait qualifier for given type indicating if edge calculations such as derivates etc. can be performed"],["FloatingPoint","Trait qualifier to accept either real or complex typed data"],["Fromf64","Trait to convert reduction's scalar output to appropriate output type"],["GrayRGBConvertible","Trait qualifier for given type indicating conversion capability between grayscale and RGB triplets of data"],["HasAfEnum","Types of the data that can be generated using ArrayFire data generation functions."],["ImageFilterType","Trait qualifier for type of Array's that are accepted by image processing functions especially filtering algorithms"],["ImageNativeType","Trait qualifier for type of Array's that are accepted by native image load/save functions."],["ImplicitPromote","This is an internal trait defined and implemented by ArrayFire create for rust's built-in types to figure out the data type binary operation's results."],["Indexable","Trait bound indicating indexability"],["IndexableType","Trait qualifier for the type of Arrays accepted by scan operations"],["IntegralType","Trait qualifier for given type indicating computability of covariance"],["MedianComputable","Trait qualifier for given type indicating computability of Median"],["MomentsComputable","Trait qualifier for given type indicating computability of Moments"],["RealFloating","Trait qualifier to accept real data(numbers)"],["RealNumber","Trait qualifier indicating it can hold real numbers only"],["ReduceByKeyInput","Trait qualifier for Reduction Key type"],["Scanable","Trait qualifier for the type of Arrays accepted by scan operations"]],"type":[["ErrorCallback","Signature of error handling callback function"],["af_array","ArrayFire FFI Type alias for af_array"],["af_event","ArrayFire FFI Type alias for af_event"],["af_features","ArrayFire FFI Type alias for af_features"],["af_index_t","ArrayFire FFI Type alias for af_indexers_t"],["af_random_engine","ArrayFire FFI Type alias for af_random_engine"],["af_window","ArrayFire FFI Type alias for af_window"],["c32","Short type alias for Complex single precision type"],["c64","Short type alias for Complex double precision type"],["dim_t","ArrayFire FFI Type alias for libc's signed long long"],["u64_t","ArrayFire FFI Type alias for libc's unsigned long long"],["void_ptr","ArrayFire FFI Type alias for libc's void*"]]}); \ No newline at end of file diff --git a/arrayfire/signal/fn.approx1.html b/arrayfire/signal/fn.approx1.html new file mode 100644 index 000000000..8efe8a51a --- /dev/null +++ b/arrayfire/signal/fn.approx1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx1_uniform.html b/arrayfire/signal/fn.approx1_uniform.html new file mode 100644 index 000000000..57be4ced1 --- /dev/null +++ b/arrayfire/signal/fn.approx1_uniform.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx1_uniform.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx1_uniform_v2.html b/arrayfire/signal/fn.approx1_uniform_v2.html new file mode 100644 index 000000000..b04ab46dd --- /dev/null +++ b/arrayfire/signal/fn.approx1_uniform_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx1_uniform_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx1_v2.html b/arrayfire/signal/fn.approx1_v2.html new file mode 100644 index 000000000..e6293e2a0 --- /dev/null +++ b/arrayfire/signal/fn.approx1_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx1_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx2.html b/arrayfire/signal/fn.approx2.html new file mode 100644 index 000000000..397225f83 --- /dev/null +++ b/arrayfire/signal/fn.approx2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx2_uniform.html b/arrayfire/signal/fn.approx2_uniform.html new file mode 100644 index 000000000..362063a0d --- /dev/null +++ b/arrayfire/signal/fn.approx2_uniform.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx2_uniform.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx2_uniform_v2.html b/arrayfire/signal/fn.approx2_uniform_v2.html new file mode 100644 index 000000000..7a956b3a2 --- /dev/null +++ b/arrayfire/signal/fn.approx2_uniform_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx2_uniform_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.approx2_v2.html b/arrayfire/signal/fn.approx2_v2.html new file mode 100644 index 000000000..9da3c31e7 --- /dev/null +++ b/arrayfire/signal/fn.approx2_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.approx2_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.convolve1.html b/arrayfire/signal/fn.convolve1.html new file mode 100644 index 000000000..7084822de --- /dev/null +++ b/arrayfire/signal/fn.convolve1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.convolve2.html b/arrayfire/signal/fn.convolve2.html new file mode 100644 index 000000000..c628eeac2 --- /dev/null +++ b/arrayfire/signal/fn.convolve2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.convolve2_sep.html b/arrayfire/signal/fn.convolve2_sep.html new file mode 100644 index 000000000..81226f517 --- /dev/null +++ b/arrayfire/signal/fn.convolve2_sep.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve2_sep.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.convolve3.html b/arrayfire/signal/fn.convolve3.html new file mode 100644 index 000000000..f92d3ac39 --- /dev/null +++ b/arrayfire/signal/fn.convolve3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.convolve3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft.html b/arrayfire/signal/fn.fft.html new file mode 100644 index 000000000..0535dab02 --- /dev/null +++ b/arrayfire/signal/fn.fft.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft2.html b/arrayfire/signal/fn.fft2.html new file mode 100644 index 000000000..9cec6f6d1 --- /dev/null +++ b/arrayfire/signal/fn.fft2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft2_c2r.html b/arrayfire/signal/fn.fft2_c2r.html new file mode 100644 index 000000000..756e4b193 --- /dev/null +++ b/arrayfire/signal/fn.fft2_c2r.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft2_c2r.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft2_inplace.html b/arrayfire/signal/fn.fft2_inplace.html new file mode 100644 index 000000000..a1abfb266 --- /dev/null +++ b/arrayfire/signal/fn.fft2_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft2_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft2_r2c.html b/arrayfire/signal/fn.fft2_r2c.html new file mode 100644 index 000000000..938ca3cef --- /dev/null +++ b/arrayfire/signal/fn.fft2_r2c.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft2_r2c.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft3.html b/arrayfire/signal/fn.fft3.html new file mode 100644 index 000000000..b58fcb1c2 --- /dev/null +++ b/arrayfire/signal/fn.fft3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft3_c2r.html b/arrayfire/signal/fn.fft3_c2r.html new file mode 100644 index 000000000..f6f498801 --- /dev/null +++ b/arrayfire/signal/fn.fft3_c2r.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft3_c2r.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft3_inplace.html b/arrayfire/signal/fn.fft3_inplace.html new file mode 100644 index 000000000..2dd2a8647 --- /dev/null +++ b/arrayfire/signal/fn.fft3_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft3_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft3_r2c.html b/arrayfire/signal/fn.fft3_r2c.html new file mode 100644 index 000000000..eb42f500a --- /dev/null +++ b/arrayfire/signal/fn.fft3_r2c.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft3_r2c.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_c2r.html b/arrayfire/signal/fn.fft_c2r.html new file mode 100644 index 000000000..8b217eb41 --- /dev/null +++ b/arrayfire/signal/fn.fft_c2r.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_c2r.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_convolve1.html b/arrayfire/signal/fn.fft_convolve1.html new file mode 100644 index 000000000..0d3943361 --- /dev/null +++ b/arrayfire/signal/fn.fft_convolve1.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_convolve1.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_convolve2.html b/arrayfire/signal/fn.fft_convolve2.html new file mode 100644 index 000000000..55597f180 --- /dev/null +++ b/arrayfire/signal/fn.fft_convolve2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_convolve2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_convolve3.html b/arrayfire/signal/fn.fft_convolve3.html new file mode 100644 index 000000000..92c06cf5b --- /dev/null +++ b/arrayfire/signal/fn.fft_convolve3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_convolve3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_inplace.html b/arrayfire/signal/fn.fft_inplace.html new file mode 100644 index 000000000..ae3e4beb7 --- /dev/null +++ b/arrayfire/signal/fn.fft_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fft_r2c.html b/arrayfire/signal/fn.fft_r2c.html new file mode 100644 index 000000000..25257d67a --- /dev/null +++ b/arrayfire/signal/fn.fft_r2c.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fft_r2c.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.fir.html b/arrayfire/signal/fn.fir.html new file mode 100644 index 000000000..9d7deddc2 --- /dev/null +++ b/arrayfire/signal/fn.fir.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fir.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft.html b/arrayfire/signal/fn.ifft.html new file mode 100644 index 000000000..55ba0e69e --- /dev/null +++ b/arrayfire/signal/fn.ifft.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft2.html b/arrayfire/signal/fn.ifft2.html new file mode 100644 index 000000000..050572cd7 --- /dev/null +++ b/arrayfire/signal/fn.ifft2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft2_inplace.html b/arrayfire/signal/fn.ifft2_inplace.html new file mode 100644 index 000000000..d24c72ddd --- /dev/null +++ b/arrayfire/signal/fn.ifft2_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft2_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft3.html b/arrayfire/signal/fn.ifft3.html new file mode 100644 index 000000000..24bf14d47 --- /dev/null +++ b/arrayfire/signal/fn.ifft3.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft3.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft3_inplace.html b/arrayfire/signal/fn.ifft3_inplace.html new file mode 100644 index 000000000..ad1efe3f1 --- /dev/null +++ b/arrayfire/signal/fn.ifft3_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft3_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.ifft_inplace.html b/arrayfire/signal/fn.ifft_inplace.html new file mode 100644 index 000000000..11ee8ff6c --- /dev/null +++ b/arrayfire/signal/fn.ifft_inplace.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.ifft_inplace.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.iir.html b/arrayfire/signal/fn.iir.html new file mode 100644 index 000000000..c6b7840fc --- /dev/null +++ b/arrayfire/signal/fn.iir.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.iir.html...

+ + + \ No newline at end of file diff --git a/arrayfire/signal/fn.set_fft_plan_cache_size.html b/arrayfire/signal/fn.set_fft_plan_cache_size.html new file mode 100644 index 000000000..6d0db280b --- /dev/null +++ b/arrayfire/signal/fn.set_fft_plan_cache_size.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.set_fft_plan_cache_size.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse.html b/arrayfire/sparse/fn.sparse.html new file mode 100644 index 000000000..b080537bb --- /dev/null +++ b/arrayfire/sparse/fn.sparse.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_convert_to.html b/arrayfire/sparse/fn.sparse_convert_to.html new file mode 100644 index 000000000..2b2a3b135 --- /dev/null +++ b/arrayfire/sparse/fn.sparse_convert_to.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_convert_to.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_from_dense.html b/arrayfire/sparse/fn.sparse_from_dense.html new file mode 100644 index 000000000..79e3ade2a --- /dev/null +++ b/arrayfire/sparse/fn.sparse_from_dense.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_from_dense.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_from_host.html b/arrayfire/sparse/fn.sparse_from_host.html new file mode 100644 index 000000000..3a2558094 --- /dev/null +++ b/arrayfire/sparse/fn.sparse_from_host.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_from_host.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_col_indices.html b/arrayfire/sparse/fn.sparse_get_col_indices.html new file mode 100644 index 000000000..bb8df548a --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_col_indices.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_col_indices.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_format.html b/arrayfire/sparse/fn.sparse_get_format.html new file mode 100644 index 000000000..2c29649ae --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_format.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_format.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_info.html b/arrayfire/sparse/fn.sparse_get_info.html new file mode 100644 index 000000000..dc746a454 --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_info.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_info.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_nnz.html b/arrayfire/sparse/fn.sparse_get_nnz.html new file mode 100644 index 000000000..e656f0898 --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_nnz.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_nnz.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_row_indices.html b/arrayfire/sparse/fn.sparse_get_row_indices.html new file mode 100644 index 000000000..a4f88ca8d --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_row_indices.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_row_indices.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_get_values.html b/arrayfire/sparse/fn.sparse_get_values.html new file mode 100644 index 000000000..045c80e4b --- /dev/null +++ b/arrayfire/sparse/fn.sparse_get_values.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_get_values.html...

+ + + \ No newline at end of file diff --git a/arrayfire/sparse/fn.sparse_to_dense.html b/arrayfire/sparse/fn.sparse_to_dense.html new file mode 100644 index 000000000..61120a334 --- /dev/null +++ b/arrayfire/sparse/fn.sparse_to_dense.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.sparse_to_dense.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.corrcoef.html b/arrayfire/statistics/fn.corrcoef.html new file mode 100644 index 000000000..3e8b52d0e --- /dev/null +++ b/arrayfire/statistics/fn.corrcoef.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.corrcoef.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.cov.html b/arrayfire/statistics/fn.cov.html new file mode 100644 index 000000000..8c8d43c03 --- /dev/null +++ b/arrayfire/statistics/fn.cov.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.cov.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.cov_v2.html b/arrayfire/statistics/fn.cov_v2.html new file mode 100644 index 000000000..542cc5403 --- /dev/null +++ b/arrayfire/statistics/fn.cov_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.cov_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.mean.html b/arrayfire/statistics/fn.mean.html new file mode 100644 index 000000000..2a540dbfb --- /dev/null +++ b/arrayfire/statistics/fn.mean.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.mean.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.mean_all.html b/arrayfire/statistics/fn.mean_all.html new file mode 100644 index 000000000..1bd00c3c5 --- /dev/null +++ b/arrayfire/statistics/fn.mean_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.mean_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.mean_all_weighted.html b/arrayfire/statistics/fn.mean_all_weighted.html new file mode 100644 index 000000000..e9889423d --- /dev/null +++ b/arrayfire/statistics/fn.mean_all_weighted.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.mean_all_weighted.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.mean_weighted.html b/arrayfire/statistics/fn.mean_weighted.html new file mode 100644 index 000000000..27bdaccfc --- /dev/null +++ b/arrayfire/statistics/fn.mean_weighted.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.mean_weighted.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.meanvar.html b/arrayfire/statistics/fn.meanvar.html new file mode 100644 index 000000000..4cf5ee478 --- /dev/null +++ b/arrayfire/statistics/fn.meanvar.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.meanvar.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.median.html b/arrayfire/statistics/fn.median.html new file mode 100644 index 000000000..e89463680 --- /dev/null +++ b/arrayfire/statistics/fn.median.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.median.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.median_all.html b/arrayfire/statistics/fn.median_all.html new file mode 100644 index 000000000..209f3bbbd --- /dev/null +++ b/arrayfire/statistics/fn.median_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.median_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.stdev.html b/arrayfire/statistics/fn.stdev.html new file mode 100644 index 000000000..cede96fb4 --- /dev/null +++ b/arrayfire/statistics/fn.stdev.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.stdev.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.stdev_all.html b/arrayfire/statistics/fn.stdev_all.html new file mode 100644 index 000000000..227e50c81 --- /dev/null +++ b/arrayfire/statistics/fn.stdev_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.stdev_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.stdev_all_v2.html b/arrayfire/statistics/fn.stdev_all_v2.html new file mode 100644 index 000000000..ad00fdc01 --- /dev/null +++ b/arrayfire/statistics/fn.stdev_all_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.stdev_all_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.stdev_v2.html b/arrayfire/statistics/fn.stdev_v2.html new file mode 100644 index 000000000..e608ff995 --- /dev/null +++ b/arrayfire/statistics/fn.stdev_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.stdev_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.topk.html b/arrayfire/statistics/fn.topk.html new file mode 100644 index 000000000..55d411a08 --- /dev/null +++ b/arrayfire/statistics/fn.topk.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.topk.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var.html b/arrayfire/statistics/fn.var.html new file mode 100644 index 000000000..a0ada5a6b --- /dev/null +++ b/arrayfire/statistics/fn.var.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var_all.html b/arrayfire/statistics/fn.var_all.html new file mode 100644 index 000000000..33d74c08b --- /dev/null +++ b/arrayfire/statistics/fn.var_all.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var_all.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var_all_v2.html b/arrayfire/statistics/fn.var_all_v2.html new file mode 100644 index 000000000..621323452 --- /dev/null +++ b/arrayfire/statistics/fn.var_all_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var_all_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var_all_weighted.html b/arrayfire/statistics/fn.var_all_weighted.html new file mode 100644 index 000000000..513f69d12 --- /dev/null +++ b/arrayfire/statistics/fn.var_all_weighted.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var_all_weighted.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var_v2.html b/arrayfire/statistics/fn.var_v2.html new file mode 100644 index 000000000..a369996bd --- /dev/null +++ b/arrayfire/statistics/fn.var_v2.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var_v2.html...

+ + + \ No newline at end of file diff --git a/arrayfire/statistics/fn.var_weighted.html b/arrayfire/statistics/fn.var_weighted.html new file mode 100644 index 000000000..400a67d85 --- /dev/null +++ b/arrayfire/statistics/fn.var_weighted.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.var_weighted.html...

+ + + \ No newline at end of file diff --git a/arrayfire/struct.Array.html b/arrayfire/struct.Array.html new file mode 100644 index 000000000..bf6f6482b --- /dev/null +++ b/arrayfire/struct.Array.html @@ -0,0 +1,526 @@ +arrayfire::Array - Rust + + + +

[][src]Struct arrayfire::Array

pub struct Array<T: HasAfEnum> { /* fields omitted */ }

A multidimensional data container

+

Currently, Array objects can store only data until four dimensions

+

Sharing Across Threads

+

While sharing an Array with other threads, there is no need to wrap +this in an Arc object unless only one such object is required to exist. +The reason being that ArrayFire's internal Array is appropriately reference +counted in thread safe manner. However, if you need to modify Array object, +then please do wrap the object using a Mutex or Read-Write lock.

+

Examples on how to share Array across threads is illustrated in our +book

+

NOTE

+

All operators(traits) from std::ops module implemented for Array object +carry out element wise operations. For example, * does multiplication of +elements at corresponding locations in two different Arrays.

+

Implementations

impl<T> Array<T> where
    T: HasAfEnum
[src]

pub fn new(slice: &[T], dims: Dim4) -> Self[src]

Constructs a new Array object

+

Examples

+

An example of creating an Array from f32 array

+ +
+use arrayfire::{Array, Dim4, print};
+let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+

An example of creating an Array from half::f16 array

+ +
+use arrayfire::{Array, Dim4, is_half_available, print};
+use half::f16;
+
+let values: [f32; 3] = [1.0, 2.0, 3.0];
+
+if is_half_available(0) { // Default device is 0, hence the argument
+    let half_values = values.iter().map(|&x| f16::from_f32(x)).collect::<Vec<_>>();
+
+    let hvals = Array::new(&half_values, Dim4::new(&[3, 1, 1, 1]));
+
+    print(&hvals);
+} else {
+    println!("Half support isn't available on this device");
+}
+

pub fn new_strided(slice: &[T], offset: i64, dims: Dim4, strides: Dim4) -> Self[src]

Constructs a new Array object from strided data

+

The data pointed by the slice passed to this function can possibily be offseted using an additional offset parameter.

+

pub fn new_empty(dims: Dim4) -> Self[src]

Constructs a new Array object of specified dimensions and type

+

Examples

+
+use arrayfire::{Array, Dim4};
+let garbage_vals = Array::<f32>::new_empty(Dim4::new(&[3, 1, 1, 1]));
+

pub fn new_from_device_ptr(dev_ptr: *mut T, dims: Dim4) -> Self[src]

Constructs a new Array object from device pointer

+

The example show cases the usage using CUDA API, but usage of this function will +be similar in CPU and OpenCL backends also. In the case of OpenCL backend, the pointer +would be cl_mem. A short example of how to create an Array from device pointer is +shown below but for detailed set of examples, please check out the tutorial book +pages:

+ +

Examples

+

An example of creating an Array device pointer using +rustacuda crate. The +example has to be copied to a bin crate with following contents in Cargo.toml +to run successfully. Note that, all required setup for rustacuda and arrayfire crate +have to completed first.

+
[package]
+....
+[dependencies]
+rustacuda = "0.1"
+rustacuda_derive = "0.1"
+rustacuda_core = "0.1"
+arrayfire = "3.7.*"
+
+ +
This example is not tested
+use arrayfire::*;
+use rustacuda::*;
+use rustacuda::prelude::*;
+
+fn main() {
+   let v: Vec<_> = (0u8 .. 100).map(f32::from).collect();
+
+   rustacuda::init(CudaFlags::empty());
+   let device = Device::get_device(0).unwrap();
+   let context = Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO,
+                                          device).unwrap();
+   // Approach 1
+   {
+       let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap();
+
+       let array_dptr = Array::new_from_device_ptr(
+           buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10));
+
+       af_print!("array_dptr", &array_dptr);
+
+       array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership
+   }
+
+   // Approach 2
+   {
+       let mut dptr: *mut f32 = std::ptr::null_mut();
+       unsafe {
+           dptr = memory::cuda_malloc::<f32>(10*10).unwrap().as_raw_mut();
+       }
+       let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));
+       // note that values might be garbage in the memory pointed out by dptr
+       // in this example as it is allocated but not initialized prior to passing
+       // along to arrayfire::Array::new*
+
+       // After ArrayFire takes over ownership of the pointer, you can use other
+       // arrayfire functions as usual.
+       af_print!("array_dptr", &array_dptr);
+   }
+}
+

pub fn get_backend(&self) -> Backend[src]

Returns the backend of the Array

+

Return Values

+

Returns an value of type Backend which indicates which backend +was active when Array was created.

+

pub fn get_device_id(&self) -> i32[src]

Returns the device identifier(integer) on which the Array was created

+

Return Values

+

Return the device id on which Array was created.

+

pub fn elements(&self) -> usize[src]

Returns the number of elements in the Array

+

pub fn get_type(&self) -> DType[src]

Returns the Array data type

+

pub fn dims(&self) -> Dim4[src]

Returns the dimensions of the Array

+

pub fn strides(&self) -> Dim4[src]

Returns the strides of the Array

+

pub fn numdims(&self) -> u32[src]

Returns the number of dimensions of the Array

+

pub fn offset(&self) -> i64[src]

Returns the offset to the pointer from where data begins

+

pub unsafe fn get(&self) -> af_array[src]

Returns the native FFI handle for Rust object Array

+

pub fn set(&mut self, handle: af_array)[src]

Set the native FFI handle for Rust object Array

+

pub fn host<O: HasAfEnum>(&self, data: &mut [O])[src]

Copies the data from the Array to the mutable slice data

+

Examples

+

Basic case

+ +
+let a:Vec<u8> = vec![0,1,2,3,4,5,6,7,8];
+let b = Array::<u8>::new(&a,Dim4::new(&[3,3,1,1]));
+let mut c = vec!(u8::default();b.elements());
+b.host(&mut c);
+assert_eq!(c,a);
+

Generic case

+ +
+fn to_vec<T:HasAfEnum+Default+Clone>(array:&Array<T>) -> Vec<T> {
+    let mut vec = vec!(T::default();array.elements());
+    array.host(&mut vec);
+    return vec;
+}
+
+let a = Array::<u8>::new(&[0,1,2,3,4,5,6,7,8],Dim4::new(&[3,3,1,1]));
+let b:Vec<u8> = vec![0,1,2,3,4,5,6,7,8];
+assert_eq!(to_vec(&a),b);
+

pub fn eval(&self)[src]

Evaluates any pending lazy expressions that represent the data in the Array object

+

pub fn copy(&self) -> Self[src]

Makes an copy of the Array

+

This does a deep copy of the data into a new Array

+

pub fn is_empty(&self) -> bool[src]

Check if Array is empty

+

pub fn is_scalar(&self) -> bool[src]

Check if Array is scalar

+

pub fn is_row(&self) -> bool[src]

Check if Array is a row

+

pub fn is_column(&self) -> bool[src]

Check if Array is a column

+

pub fn is_vector(&self) -> bool[src]

Check if Array is a vector

+

pub fn is_real(&self) -> bool[src]

Check if Array is of real (not complex) type

+

pub fn is_complex(&self) -> bool[src]

Check if Array is of complex type

+

pub fn is_double(&self) -> bool[src]

Check if Array's numerical type is of double precision

+

pub fn is_single(&self) -> bool[src]

Check if Array's numerical type is of single precision

+

pub fn is_half(&self) -> bool[src]

Check if Array's numerical type is of half precision

+

pub fn is_integer(&self) -> bool[src]

Check if Array is of integral type

+

pub fn is_bool(&self) -> bool[src]

Check if Array is of boolean type

+

pub fn is_realfloating(&self) -> bool[src]

Check if Array is floating point real(not complex) data type

+

pub fn is_floating(&self) -> bool[src]

Check if Array is floating point type, either real or complex data

+

pub fn is_linear(&self) -> bool[src]

Check if Array's memory layout is continuous and one dimensional

+

pub fn is_sparse(&self) -> bool[src]

Check if Array is a sparse matrix

+

pub fn is_owner(&self) -> bool[src]

Check if Array's memory is owned by it and not a view of another Array

+

pub fn cast<O: HasAfEnum>(&self) -> Array<O>[src]

Cast the Array data type to target_type

+

pub fn lock(&self)[src]

Lock the device buffer in the memory manager

+

Locked buffers are not freed by memory manager until unlock is called.

+

pub fn unlock(&self)[src]

Unlock the device buffer in the memory manager

+

This function will give back the control over the device pointer to the +memory manager.

+

pub unsafe fn device_ptr(&self) -> void_ptr[src]

Get the device pointer and lock the buffer in memory manager

+

The device pointer is not freed by memory manager until unlock is called.

+

pub fn get_allocated_bytes(&self) -> usize[src]

Get the size of physical allocated bytes.

+

This function will return the size of the parent/owner if the current Array object is an +indexed Array.

+

Trait Implementations

impl<'a, A, B> Add<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the + operator.

+

impl<'a, 'b, A, B> Add<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T> Add<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<A, B> Add<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the + operator.

+

impl<'a, A, B> Add<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<T> Add<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the + operator.

+

impl<'f, T, U> Add<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the + operator.

+

impl<T, U> Add<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the + operator.

+

impl<A, B> AddAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<'a, A, B> BitAnd<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the & operator.

+

impl<'a, 'b, A, B> BitAnd<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the & operator.

+

impl<A, B> BitAnd<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the & operator.

+

impl<'a, A, B> BitAnd<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the & operator.

+

impl<A, B> BitAndAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<'a, A, B> BitOr<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the | operator.

+

impl<'a, 'b, A, B> BitOr<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the | operator.

+

impl<A, B> BitOr<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the | operator.

+

impl<'a, A, B> BitOr<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the | operator.

+

impl<A, B> BitOrAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<'a, A, B> BitXor<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the ^ operator.

+

impl<'a, 'b, A, B> BitXor<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the ^ operator.

+

impl<A, B> BitXor<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the ^ operator.

+

impl<'a, A, B> BitXor<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the ^ operator.

+

impl<A, B> BitXorAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T> Clone for Array<T> where
    T: HasAfEnum
[src]

Returns a new Array object after incrementing the reference count of native resource

+

Cloning an Array does not do a deep copy of the underlying array data. It increments the +reference count of native resource and returns you the new reference in the form a new Array +object.

+

To create a deep copy use +copy()

+

impl<T: HasAfEnum> Convertable for Array<T>[src]

type OutType = T

This type alias always points to Self which is the +type of Array returned by the +trait method convert. Read more

+

impl<'a, A, B> Div<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the / operator.

+

impl<'a, 'b, A, B> Div<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T> Div<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<A, B> Div<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the / operator.

+

impl<'a, A, B> Div<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<T> Div<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the / operator.

+

impl<'f, T, U> Div<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the / operator.

+

impl<T, U> Div<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the / operator.

+

impl<A, B> DivAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T> Drop for Array<T> where
    T: HasAfEnum
[src]

To free resources when Array goes out of scope

+

impl<T> Indexable for Array<T> where
    T: HasAfEnum + IndexableType
[src]

Enables Array to be used to index another Array

+

This is used in functions index_gen and +assign_gen

+

impl<T: HasAfEnum> Into<Array<T>> for af_array[src]

Used for creating Array object from native +resource id, an 64 bit integer

+

impl<'a, A, B> Mul<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the * operator.

+

impl<'a, 'b, A, B> Mul<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T> Mul<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<A, B> Mul<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the * operator.

+

impl<'a, A, B> Mul<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<T> Mul<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the * operator.

+

impl<'f, T, U> Mul<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the * operator.

+

impl<T, U> Mul<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the * operator.

+

impl<A, B> MulAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T> Neg for Array<T> where
    T: Zero + ConstGenerator<OutType = T>, 
[src]

Implement negation trait for Array

+

type Output = Array<T>

The resulting type after applying the - operator.

+

impl<'f, T> Not for &'f Array<T> where
    T: HasAfEnum
[src]

Enables use of ! on objects of type Array

+

type Output = Array<T>

The resulting type after applying the ! operator.

+

impl<'a, A, B> Rem<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the % operator.

+

impl<'a, 'b, A, B> Rem<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the % operator.

+

impl<A, B> Rem<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the % operator.

+

impl<'a, A, B> Rem<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the % operator.

+

impl<A, B> RemAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T: HasAfEnum> Send for Array<T>[src]

Enable safely moving Array objects across threads

+

impl<'a, A, B> Shl<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the << operator.

+

impl<'a, 'b, A, B> Shl<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the << operator.

+

impl<A, B> Shl<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the << operator.

+

impl<'a, A, B> Shl<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the << operator.

+

impl<T> Shl<u16> for Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u16>>::Output>

The resulting type after applying the << operator.

+

impl<'f, T> Shl<u16> for &'f Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u16>>::Output>

The resulting type after applying the << operator.

+

impl<T> Shl<u32> for Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u32>>::Output>

The resulting type after applying the << operator.

+

impl<'f, T> Shl<u32> for &'f Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u32>>::Output>

The resulting type after applying the << operator.

+

impl<T> Shl<u64> for Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u64>>::Output>

The resulting type after applying the << operator.

+

impl<'f, T> Shl<u64> for &'f Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u64>>::Output>

The resulting type after applying the << operator.

+

impl<T> Shl<u8> for Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u8>>::Output>

The resulting type after applying the << operator.

+

impl<'f, T> Shl<u8> for &'f Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u8>>::Output>

The resulting type after applying the << operator.

+

impl<A, B> ShlAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T> ShlAssign<u16> for Array<T> where
    u16: ImplicitPromote<T>,
    T: ImplicitPromote<u16, Output = T>, 
[src]

impl<T> ShlAssign<u32> for Array<T> where
    u32: ImplicitPromote<T>,
    T: ImplicitPromote<u32, Output = T>, 
[src]

impl<T> ShlAssign<u64> for Array<T> where
    u64: ImplicitPromote<T>,
    T: ImplicitPromote<u64, Output = T>, 
[src]

impl<T> ShlAssign<u8> for Array<T> where
    u8: ImplicitPromote<T>,
    T: ImplicitPromote<u8, Output = T>, 
[src]

impl<'a, A, B> Shr<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the >> operator.

+

impl<'a, 'b, A, B> Shr<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the >> operator.

+

impl<A, B> Shr<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the >> operator.

+

impl<'a, A, B> Shr<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the >> operator.

+

impl<T> Shr<u16> for Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u16>>::Output>

The resulting type after applying the >> operator.

+

impl<'f, T> Shr<u16> for &'f Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u16>>::Output>

The resulting type after applying the >> operator.

+

impl<T> Shr<u32> for Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u32>>::Output>

The resulting type after applying the >> operator.

+

impl<'f, T> Shr<u32> for &'f Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u32>>::Output>

The resulting type after applying the >> operator.

+

impl<T> Shr<u64> for Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u64>>::Output>

The resulting type after applying the >> operator.

+

impl<'f, T> Shr<u64> for &'f Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u64>>::Output>

The resulting type after applying the >> operator.

+

impl<T> Shr<u8> for Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u8>>::Output>

The resulting type after applying the >> operator.

+

impl<'f, T> Shr<u8> for &'f Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<T as ImplicitPromote<u8>>::Output>

The resulting type after applying the >> operator.

+

impl<A, B> ShrAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T> ShrAssign<u16> for Array<T> where
    u16: ImplicitPromote<T>,
    T: ImplicitPromote<u16, Output = T>, 
[src]

impl<T> ShrAssign<u32> for Array<T> where
    u32: ImplicitPromote<T>,
    T: ImplicitPromote<u32, Output = T>, 
[src]

impl<T> ShrAssign<u64> for Array<T> where
    u64: ImplicitPromote<T>,
    T: ImplicitPromote<u64, Output = T>, 
[src]

impl<T> ShrAssign<u8> for Array<T> where
    u8: ImplicitPromote<T>,
    T: ImplicitPromote<u8, Output = T>, 
[src]

impl<'a, A, B> Sub<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the - operator.

+

impl<'a, 'b, A, B> Sub<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T> Sub<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<A, B> Sub<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the - operator.

+

impl<'a, A, B> Sub<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

type Output = Array<<A as ImplicitPromote<B>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f64> as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
[src]

type Output = Array<<Complex<f32> as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
[src]

type Output = Array<<f64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
[src]

type Output = Array<<f32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
[src]

type Output = Array<<u64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
[src]

type Output = Array<<i64 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
[src]

type Output = Array<<u32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
[src]

type Output = Array<<i32 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<T> Sub<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
[src]

type Output = Array<<u8 as ImplicitPromote<T>>::Output>

The resulting type after applying the - operator.

+

impl<'f, T, U> Sub<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the - operator.

+

impl<T, U> Sub<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
[src]

type Output = Array<<T as ImplicitPromote<U>>::Output>

The resulting type after applying the - operator.

+

impl<A, B> SubAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
[src]

impl<T: HasAfEnum> Sync for Array<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for Array<T> where
    T: RefUnwindSafe

impl<T> Unpin for Array<T> where
    T: Unpin

impl<T> UnwindSafe for Array<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, Rhs> NumAssignOps<Rhs> for T where
    T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>, 
[src]

impl<T, Rhs, Output> NumOps<Rhs, Output> for T where
    T: Sub<Rhs, Output = Output> + Mul<Rhs, Output = Output> + Div<Rhs, Output = Output> + Add<Rhs, Output = Output> + Rem<Rhs, Output = Output>, 
[src]

impl<T, Base> RefNum<Base> for T where
    T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Callback.html b/arrayfire/struct.Callback.html new file mode 100644 index 000000000..5ec0d87e3 --- /dev/null +++ b/arrayfire/struct.Callback.html @@ -0,0 +1,27 @@ +arrayfire::Callback - Rust + + + +

[][src]Struct arrayfire::Callback

pub struct Callback { /* fields omitted */ }

Structure holding handle to callback function

+

Implementations

impl Callback[src]

pub fn new(callback: ErrorCallback) -> Self[src]

Associated function to create a new Callback object

+

pub fn call(&self, error_code: AfError)[src]

call invokes the error callback with error_code.

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Dim4.html b/arrayfire/struct.Dim4.html new file mode 100644 index 000000000..2aa21c2c0 --- /dev/null +++ b/arrayfire/struct.Dim4.html @@ -0,0 +1,75 @@ +arrayfire::Dim4 - Rust + + + +

[][src]Struct arrayfire::Dim4

pub struct Dim4 { /* fields omitted */ }

Dim4 is used to store Array dimensions

+

Implementations

impl Dim4[src]

pub fn new(dims: &[u64; 4]) -> Self[src]

Create Dim4 object

+

Examples

+
+use arrayfire::Dim4;
+let dims = Dim4::new(&[4, 4, 2, 1]);
+

pub fn elements(&self) -> u64[src]

Get the number of elements represented by Dim4 object

+

pub fn ndims(&self) -> usize[src]

Get the number of dimensions of Dim4

+

pub fn get(&self) -> &[u64; 4][src]

Get the dimensions as a slice of 4 values

+

Trait Implementations

impl Clone for Dim4[src]

impl Copy for Dim4[src]

impl Debug for Dim4[src]

impl Default for Dim4[src]

Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1]

+

impl Display for Dim4[src]

Enables use of Dim4 objects for printing it to display

+

Examples

+
+use arrayfire::Dim4;
+
+let dims = Dim4::new(&[4, 4, 2, 1]);
+println!("0th Dimension length is {}", dims[0]); // -> 4
+

impl Index<usize> for Dim4[src]

Enables index operation for Dim4

+

Examples

+
+use arrayfire::Dim4;
+
+let dims = Dim4::new(&[4, 4, 2, 1]);
+println!("0th Dimension length is {}", dims[0]); // -> 4
+println!("1th Dimension length is {}", dims[1]); // -> 4
+println!("2th Dimension length is {}", dims[2]); // -> 2
+println!("3th Dimension length is {}", dims[3]); // -> 1
+

type Output = u64

The returned type after indexing.

+

impl IndexMut<usize> for Dim4[src]

Enables index operation for Dim4 to modify dimensions

+

Examples

+
+use arrayfire::Dim4;
+
+let mut dims = Dim4::new(&[4, 4, 2, 1]);
+dims[2] = 4;
+println!("Dimensions: {}", dims); // note that third dimension changed to 4
+

impl PartialEq<Dim4> for Dim4[src]

impl StructuralPartialEq for Dim4[src]

Auto Trait Implementations

impl RefUnwindSafe for Dim4

impl Send for Dim4

impl Sync for Dim4

impl Unpin for Dim4

impl UnwindSafe for Dim4

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Event.html b/arrayfire/struct.Event.html new file mode 100644 index 000000000..21604c9e3 --- /dev/null +++ b/arrayfire/struct.Event.html @@ -0,0 +1,38 @@ +arrayfire::Event - Rust + + + +

[][src]Struct arrayfire::Event

pub struct Event { /* fields omitted */ }

RAII construct to manage ArrayFire events

+

Sharing Across Threads

+

While sharing an Event with other threads, just move it across threads.

+

Implementations

impl Event[src]

pub fn mark(&self)[src]

Marks the event on the active computation queue.

+

If the event is enqueued/waited on later, any operations that are currently +enqueued on the event queue will be completed before any events that are +enqueued after the call to enqueue

+

pub fn enqueue_wait(&self)[src]

Enqueues the event and all enqueued events on the active queue

+

All operations enqueued after a call to enqueue will not be executed +until operations on the queue when mark was called are complete

+

pub fn block(&self)[src]

Blocks the calling thread on events until all events on the computation +stream before mark was called are complete

+

Trait Implementations

impl Default for Event[src]

impl Drop for Event[src]

impl Send for Event[src]

Auto Trait Implementations

impl RefUnwindSafe for Event

impl !Sync for Event

impl Unpin for Event

impl UnwindSafe for Event

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Features.html b/arrayfire/struct.Features.html new file mode 100644 index 000000000..ec3af7725 --- /dev/null +++ b/arrayfire/struct.Features.html @@ -0,0 +1,58 @@ +arrayfire::Features - Rust + + + +

[][src]Struct arrayfire::Features

pub struct Features { /* fields omitted */ }

A set of Array objects (usually, used in Computer vision context)

+

Features struct is used by computer vision functions +to return the outcome of their operation. Typically, such output +has the following Arrays:

+
    +
  • X positions of the features
  • +
  • Y positions of the features
  • +
  • Scores of the features
  • +
  • Orientations of the features
  • +
  • Sizes of the features
  • +
+

Sharing Across Threads

+

While sharing this object with other threads, there is no need to wrap +this in an Arc object unless only one such object is required to exist. +The reason being that ArrayFire's internal details that are pointed to +by the features handle are appropriately reference counted in thread safe +manner. However, if these features are to be edited, then please do wrap +the object using a Mutex or Read-Write lock.

+

Implementations

impl Features[src]

pub fn new(n: u64) -> Self[src]

Create and return an object of type Features

+

This object is basically a bunch of Arrays.

+

pub fn num_features(&self) -> i64[src]

Get total number of features found

+

pub fn xpos(&self) -> Array<f32>[src]

Get x coordinates Array

+

pub fn ypos(&self) -> Array<f32>[src]

Get y coordinates Array

+

pub fn score(&self) -> Array<f32>[src]

Get score Array

+

pub fn orientation(&self) -> Array<f32>[src]

Get orientation Array

+

pub fn size(&self) -> Array<f32>[src]

Get features size Array

+

pub unsafe fn get(&self) -> af_features[src]

Get the internal handle for Features object

+

Trait Implementations

impl Clone for Features[src]

impl Drop for Features[src]

impl Send for Features[src]

impl Sync for Features[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Indexer.html b/arrayfire/struct.Indexer.html new file mode 100644 index 000000000..c1e60fa88 --- /dev/null +++ b/arrayfire/struct.Indexer.html @@ -0,0 +1,80 @@ +arrayfire::Indexer - Rust + + + +

[][src]Struct arrayfire::Indexer

pub struct Indexer<'object> { /* fields omitted */ }

Struct to manage an array of resources of type af_indexer_t(ArrayFire C struct)

+

Sharing Across Threads

+

While sharing an Indexer object with other threads, just move it across threads. At the +moment, one cannot share borrowed references across threads.

+

Examples

+

Given below are examples illustrating correct and incorrect usage of Indexer struct.

+

Correct Usage

+ +
+use arrayfire::{Array, Dim4, randu, index_gen, Indexer};
+
+// Always be aware of the fact that, the `Seq` or `Array` objects
+// that we intend to use for indexing via `Indexer` have to outlive
+// the `Indexer` object created in this context.
+
+let dims    = Dim4::new(&[1, 3, 1, 1]);
+let indices = [1u8, 0, 1];
+let idx     = Array::new(&indices, dims);
+let values  = [2.0f32, 5.0, 6.0];
+let arr     = Array::new(&values, dims);
+
+let mut idxr = Indexer::default();
+
+// `idx` is created much before idxr, thus will
+// stay in scope at least as long as idxr
+idxr.set_index(&idx, 0, None);
+
+index_gen(&arr, idxr);
+

Incorrect Usage

+ +
This example is not tested
+// Say, you create an Array on the fly and try
+// to call set_index, it will throw the given below
+// error or something similar to that
+idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
+
error: borrowed value does not live long enough
+  --> <anon>:16:55
+  |
+16 | idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
+  |                 ----------------------------          ^ temporary value dropped here while still borrowed
+  |                 |
+  |                 temporary value created here
+...
+19 | }
+  | - temporary value needs to live until here
+  |
+  = note: consider using a `let` binding to increase its lifetime
+
+

Implementations

impl<'object> Indexer<'object>[src]

pub fn new() -> Self[src]

👎 Deprecated since 3.7.0:

Use Indexer::default() instead

+

Create a new Indexer object and set the dimension specific index objects later

+

pub fn set_index<'s, T>(
    &'s mut self,
    idx: &'object T,
    dim: u32,
    is_batch: Option<bool>
) where
    T: Indexable + 'object, 
[src]

Set either Array or Seq to index an Array along idx dimension

+

pub fn len(&self) -> usize[src]

Get number of indexing objects set

+

pub fn is_empty(&self) -> bool[src]

Check if any indexing objects are set

+

pub unsafe fn get(&self) -> af_index_t[src]

Get native(ArrayFire) resource handle

+

Trait Implementations

impl<'object> Default for Indexer<'object>[src]

impl<'object> Drop for Indexer<'object>[src]

impl<'object> Send for Indexer<'object>[src]

Auto Trait Implementations

impl<'object> RefUnwindSafe for Indexer<'object>

impl<'object> !Sync for Indexer<'object>

impl<'object> Unpin for Indexer<'object>

impl<'object> UnwindSafe for Indexer<'object>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.RandomEngine.html b/arrayfire/struct.RandomEngine.html new file mode 100644 index 000000000..feb3d474f --- /dev/null +++ b/arrayfire/struct.RandomEngine.html @@ -0,0 +1,57 @@ +arrayfire::RandomEngine - Rust + + + +

[][src]Struct arrayfire::RandomEngine

pub struct RandomEngine { /* fields omitted */ }

Random number generator engine

+

This is a wrapper for ArrayFire's native random number generator engine.

+

Sharing Across Threads

+

While sharing this object with other threads, there is no need to wrap +this in an Arc object unless only one such object is required to exist. +The reason being that ArrayFire's internal details that are pointed to +by the RandoMEngine handle are appropriately reference counted in thread safe +manner. However, if you need to modify RandomEngine object, then please do wrap +the object using a Mutex or Read-Write lock.

+

Implementations

impl RandomEngine[src]

pub fn new(rengine: RandomEngineType, seed: Option<u64>) -> Self[src]

Create a new random engine object

+

Parameters

+
    +
  • rengine can be value of RandomEngineType enum.
  • +
  • seed is the initial seed value
  • +
+

Return Values

+

A object of type RandomEngine

+

pub fn get_type(&self) -> RandomEngineType[src]

Get random engine type

+

pub fn set_type(&mut self, engine_type: RandomEngineType)[src]

Get random engine type

+

pub fn set_seed(&mut self, seed: u64)[src]

Set seed for random engine

+

pub fn get_seed(&self) -> u64[src]

Get seed of the random engine

+

pub unsafe fn get(&self) -> af_random_engine[src]

Returns the native FFI handle for Rust object RandomEngine

+

Trait Implementations

impl Clone for RandomEngine[src]

Increment reference count of RandomEngine's native resource

+

impl Drop for RandomEngine[src]

Free RandomEngine's native resource

+

impl From<*mut c_void> for RandomEngine[src]

Used for creating RandomEngine object from native resource id

+

impl Send for RandomEngine[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Seq.html b/arrayfire/struct.Seq.html new file mode 100644 index 000000000..5f8d0da2b --- /dev/null +++ b/arrayfire/struct.Seq.html @@ -0,0 +1,48 @@ +arrayfire::Seq - Rust + + + +

[][src]Struct arrayfire::Seq

#[repr(C)]pub struct Seq<T: IndexableType> { /* fields omitted */ }

Sequences are used for indexing Arrays

+

Implementations

impl<T> Seq<T> where
    T: Copy + IndexableType
[src]

pub fn new(begin: T, end: T, step: T) -> Self[src]

Create a Seq that goes from begin to end at a step size of step

+

pub fn begin(&self) -> T[src]

Get begin index of Seq

+

pub fn end(&self) -> T[src]

Get end index of Seq

+

pub fn step(&self) -> T[src]

Get step size of Seq

+

Trait Implementations

impl<T: Clone + IndexableType> Clone for Seq<T>[src]

impl<T: Copy + IndexableType> Copy for Seq<T>[src]

impl<T: Debug + IndexableType> Debug for Seq<T>[src]

impl<T> Default for Seq<T> where
    T: One + Zero + IndexableType
[src]

Default Seq spans all the elements along a dimension

+

impl<T> Display for Seq<T> where
    T: Display + IndexableType
[src]

Enables use of Seq with {} format in print statements

+

impl<T> Indexable for Seq<T> where
    c_double: From<T>,
    T: Copy + IndexableType
[src]

Enables Seq to be used to index another Array

+

This is used in functions index_gen and +assign_gen

+

impl<T: PartialEq + IndexableType> PartialEq<Seq<T>> for Seq<T>[src]

impl<T: IndexableType> StructuralPartialEq for Seq<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for Seq<T> where
    T: RefUnwindSafe

impl<T> Send for Seq<T> where
    T: Send

impl<T> Sync for Seq<T> where
    T: Sync

impl<T> Unpin for Seq<T> where
    T: Unpin

impl<T> UnwindSafe for Seq<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/struct.Window.html b/arrayfire/struct.Window.html new file mode 100644 index 000000000..7de780579 --- /dev/null +++ b/arrayfire/struct.Window.html @@ -0,0 +1,278 @@ +arrayfire::Window - Rust + + + +

[][src]Struct arrayfire::Window

pub struct Window { /* fields omitted */ }

Used to render Array objects

+

The renderings can be either plots, histograms or simply just image displays. +A single window can also display multiple of the above renderings at the same time, which +is known as multiview mode. An example of that is given below.

+

Examples

+
+use arrayfire::{histogram, load_image, Window};
+let mut wnd = Window::new(1280, 720, String::from("Image Histogram"));
+let img = load_image::<f32>("Path to image".to_string(), true/*If color image, 'false' otherwise*/);
+let hst = histogram(&img, 256, 0 as f64, 255 as f64);
+
+loop {
+    wnd.grid(2, 1);
+
+    wnd.set_view(0, 0);
+    wnd.draw_image(&img, Some("Input Image".to_string()));
+
+    wnd.set_view(1, 0);
+    wnd.draw_hist(&hst, 0.0, 255.0, Some("Input Image Histogram".to_string()));
+
+    wnd.show();
+
+    if wnd.is_closed() == true { break; }
+}
+

Implementations

impl Window[src]

pub fn new(width: i32, height: i32, title: String) -> Self[src]

Creates new Window object

+

Parameters

+
    +
  • width is width of the window
  • +
  • height is the height of window
  • +
  • title is the string displayed on window title bar
  • +
+

Return Values

+

Window Object

+

pub fn set_position(&self, x: u32, y: u32)[src]

Set window starting position on the screen

+

Parameters

+
    +
  • x is the horiontal coordinate where window is to be placed
  • +
  • y is the vertical coordinate where window is to be placed
  • +
+

pub fn set_title(&self, title: String)[src]

Set window title

+

Parameters

+
    +
  • title is the string to be displayed on window title bar
  • +
+

pub fn set_visibility(&self, is_visible: bool)[src]

Set window visibility

+

Parameters

+
    +
  • is_visible is a boolean indicating whether window is to be hidden or brought into focus
  • +
+

Return Values

+

None

+

pub fn set_size(&self, w: u32, h: u32)[src]

Set window size

+

Parameters

+
    +
  • w is the target width of window
  • +
  • h is the target height of window
  • +
+

pub fn set_colormap(&mut self, cmap: ColorMap)[src]

Set color map to be used for rendering image, it can take one of the values of enum +ColorMap

+

pub fn is_closed(&self) -> bool[src]

Returns true if the window close is triggered by the user

+

pub fn grid(&self, rows: i32, cols: i32)[src]

Setup display layout in multiview mode

+

Parameters

+
    +
  • rows is the number of rows into which whole window is split into in multiple view mode
  • +
  • cols is the number of cols into which whole window is split into in multiple view mode
  • +
+

pub fn show(&mut self)[src]

Used in multiview mode to swap back buffer with front buffer to show the recently rendered +frame

+

pub fn set_view(&mut self, r: i32, c: i32)[src]

Set the current sub-region to render

+

This function is only to be used into multiview mode

+

Parameters

+
    +
  • r is the target row id
  • +
  • c is the target row id
  • +
+

pub fn set_axes_titles(
    &mut self,
    xlabel: String,
    ylabel: String,
    zlabel: String
)
[src]

Set chart axes titles

+

Parameters

+
    +
  • xlabel is x axis title
  • +
  • ylabel is y axis title
  • +
  • zlabel is z axis title
  • +
+

pub fn set_axes_label_format(
    &mut self,
    xlabel_format: String,
    ylabel_format: String,
    zlabel_format: String
)
[src]

Set chart axes labels format

+

Parameters

+
    +
  • xlabel_format is x axis label format. format specific is identical to C's printf format
  • +
  • ylabel_format is y axis label format. format specific is identical to C's printf format
  • +
  • zlabel_format is z axis label format. format specific is identical to C's printf format
  • +
+

pub fn set_axes_label_formats(
    &mut self,
    xformat: String,
    yformat: String,
    zformat: String
)
[src]

Set chart axes labels formats

+

Axes labels use printf style format specifiers. Default specifier for the data displayed +as labels is %4.1f. This function lets the user change this label formatting to whichever +format that fits their data range and precision.

+

Parameters

+
    +
  • xlabel is printf style format specifier for x axis
  • +
  • ylabel is printf style format specifier for y axis
  • +
  • zlabel is printf style format specifier for z axis
  • +
+

pub fn set_axes_limits_compute<T>(
    &mut self,
    xrange: &Array<T>,
    yrange: &Array<T>,
    zrange: Option<&Array<T>>,
    exact: bool
) where
    T: HasAfEnum
[src]

Set chart axes limits by computing limits from data

+

In multiple view (grid) mode, setting limits will effect the chart that is currently +active via set_view call

+

Parameters

+
    +
  • xrange is set of all x values to compute min/max for x axis
  • +
  • yrange is set of all y values to compute min/max for y axis
  • +
  • zrange is set of all z values to compute min/max for z axis. If None is passed to +this paramter, 2d chart limits are set.
  • +
  • exact indicates if the exact min/max values from xrange, yrange and zrange +are to extracted. If exact is false then the most significant digit is rounded up +to next power of 2 and the magnitude remains the same.
  • +
+

pub fn set_axes_limits_2d(
    &mut self,
    xmin: f32,
    xmax: f32,
    ymin: f32,
    ymax: f32,
    exact: bool
)
[src]

Set 2d chart axes limits

+

In multiple view (grid) mode, setting limits will effect the chart that is currently +active via set_view call

+

Parameters

+
    +
  • xmin is minimum value on x axis
  • +
  • xmax is maximum value on x axis
  • +
  • ymin is minimum value on y axis
  • +
  • ymax is maximum value on y axis
  • +
  • exact indicates if the exact min/max values from xrange, yrange and zrange +are to extracted. If exact is false then the most significant digit is rounded up +to next power of 2 and the magnitude remains the same.
  • +
+

pub fn set_axes_limits_3d(
    &mut self,
    xmin: f32,
    xmax: f32,
    ymin: f32,
    ymax: f32,
    zmin: f32,
    zmax: f32,
    exact: bool
)
[src]

Set 3d chart axes limits

+

In multiple view (grid) mode, setting limits will effect the chart that is currently +active via set_view call

+

Parameters

+
    +
  • xmin is minimum value on x axis
  • +
  • xmax is maximum value on x axis
  • +
  • ymin is minimum value on y axis
  • +
  • ymax is maximum value on y axis
  • +
  • zmin is minimum value on z axis
  • +
  • zmax is maximum value on z axis
  • +
  • exact indicates if the exact min/max values from xrange, yrange and zrange +are to extracted. If exact is false then the most significant digit is rounded up +to next power of 2 and the magnitude remains the same.
  • +
+

pub fn draw_image<T>(&self, input: &Array<T>, title: Option<String>) where
    T: HasAfEnum
[src]

Render given Array as an image

+

Parameters

+
    +
  • input image
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_plot2<T>(&self, x: &Array<T>, y: &Array<T>, title: Option<String>) where
    T: HasAfEnum
[src]

Render given two Array's x and y as a 2d line plot

+

Parameters

+
    +
  • x is the x coordinates of the plot
  • +
  • y is the y coordinates of the plot
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_plot3<T>(
    &self,
    x: &Array<T>,
    y: &Array<T>,
    z: &Array<T>,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Array's x, y and z as a 3d line plot

+

Parameters

+
    +
  • x is the x coordinates of the plot
  • +
  • y is the y coordinates of the plot
  • +
  • z is the z coordinates of the plot
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_plot<T>(&self, points: &Array<T>, title: Option<String>) where
    T: HasAfEnum
[src]

Render give Arrays of points as a 3d line plot

+

Parameters

+
    +
  • points is an Array containing list of points of plot
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_hist<T>(
    &self,
    hst: &Array<T>,
    minval: f64,
    maxval: f64,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Array as a histogram

+

Parameters

+
    +
  • hst is an Array containing histogram data
  • +
  • minval is the minimum bin value of histogram
  • +
  • maxval is the maximum bin value of histogram
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_surface<T>(
    &self,
    xvals: &Array<T>,
    yvals: &Array<T>,
    zvals: &Array<T>,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render give Arrays as 3d surface

+

Parameters

+
    +
  • x is the x coordinates of the surface plot
  • +
  • y is the y coordinates of the surface plot
  • +
  • z is the z coordinates of the surface plot
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_scatter2<T>(
    &self,
    xvals: &Array<T>,
    yvals: &Array<T>,
    marker: MarkerType,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Arrays as 2d scatter plot

+

Parameters

+
    +
  • xvals is the x coordinates of the scatter plot
  • +
  • yvals is the y coordinates of the scatter plot
  • +
  • marker is of enum type MarkerType
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_scatter3<T>(
    &self,
    xvals: &Array<T>,
    yvals: &Array<T>,
    zvals: &Array<T>,
    marker: MarkerType,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Arrays as 3d scatter plot

+

Parameters

+
    +
  • xvals is the x coordinates of the scatter plot
  • +
  • yvals is the y coordinates of the scatter plot
  • +
  • zvals is the z coordinates of the scatter plot
  • +
  • marker is of enum type MarkerType
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_scatter<T>(
    &self,
    vals: &Array<T>,
    marker: MarkerType,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render give Array as 3d scatter plot

+

Parameters

+
    +
  • points is an Array containing list of points of plot
  • +
  • marker is of enum type MarkerType
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_vector_field2<T>(
    &self,
    xpnts: &Array<T>,
    ypnts: &Array<T>,
    xdirs: &Array<T>,
    ydirs: &Array<T>,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Arrays as 2d vector field

+

Parameters

+
    +
  • xpnts is an Array containing list of x coordinates
  • +
  • xdirs is an Array containing direction component of x coord
  • +
  • ypnts is an Array containing list of y coordinates
  • +
  • ydirs is an Array containing direction component of y coord
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_vector_field3<T>(
    &self,
    xpnts: &Array<T>,
    ypnts: &Array<T>,
    zpnts: &Array<T>,
    xdirs: &Array<T>,
    ydirs: &Array<T>,
    zdirs: &Array<T>,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Arrays as 3d vector field

+

Parameters

+
    +
  • xpnts is an Array containing list of x coordinates
  • +
  • xdirs is an Array containing direction component of x coord
  • +
  • ypnts is an Array containing list of y coordinates
  • +
  • ydirs is an Array containing direction component of y coord
  • +
  • zpnts is an Array containing list of z coordinates
  • +
  • zdirs is an Array containing direction component of z coord
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

pub fn draw_vector_field<T>(
    &self,
    points: &Array<T>,
    directions: &Array<T>,
    title: Option<String>
) where
    T: HasAfEnum
[src]

Render given Array as vector field

+

Parameters

+
    +
  • points is an Array containing list of coordinates of vector field
  • +
  • directions is an Array containing directions at the coordinates specified in points +Array.
  • +
  • title parameter has effect only in multiview mode, where this string +is displayed as the respective cell/view title.
  • +
+

Trait Implementations

impl Clone for Window[src]

impl Drop for Window[src]

Auto Trait Implementations

impl RefUnwindSafe for Window

impl !Send for Window

impl !Sync for Window

impl Unpin for Window

impl UnwindSafe for Window

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/arrayfire/trait.ComplexFloating.html b/arrayfire/trait.ComplexFloating.html new file mode 100644 index 000000000..8abcd4526 --- /dev/null +++ b/arrayfire/trait.ComplexFloating.html @@ -0,0 +1,16 @@ +arrayfire::ComplexFloating - Rust + + + +

[][src]Trait arrayfire::ComplexFloating

pub trait ComplexFloating: HasAfEnum { }

Trait qualifier to accept complex data(numbers)

+

Implementors

impl ComplexFloating for c32[src]

impl ComplexFloating for c64[src]

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ConfidenceCCInput.html b/arrayfire/trait.ConfidenceCCInput.html new file mode 100644 index 000000000..b565a67c1 --- /dev/null +++ b/arrayfire/trait.ConfidenceCCInput.html @@ -0,0 +1,16 @@ +arrayfire::ConfidenceCCInput - Rust + + + +

[][src]Trait arrayfire::ConfidenceCCInput

pub trait ConfidenceCCInput: HasAfEnum { }

Trait qualifier for confidence connected components input

+

Implementations on Foreign Types

impl ConfidenceCCInput for f32[src]

impl ConfidenceCCInput for u32[src]

impl ConfidenceCCInput for u16[src]

impl ConfidenceCCInput for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ConstGenerator.html b/arrayfire/trait.ConstGenerator.html new file mode 100644 index 000000000..5000310fd --- /dev/null +++ b/arrayfire/trait.ConstGenerator.html @@ -0,0 +1,40 @@ +arrayfire::ConstGenerator - Rust + + + +

[][src]Trait arrayfire::ConstGenerator

pub trait ConstGenerator: HasAfEnum {
+    type OutType: HasAfEnum;
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType>;
+}

Type Trait to generate a constant Array of given size

+

Internally, ConstGenerator trait is implemented by following types.

+
    +
  • f32
  • +
  • f64
  • +
  • num::Complex<f32>
  • +
  • num::Complex<f64>
  • +
  • bool
  • +
  • i32
  • +
  • u32
  • +
  • u8
  • +
  • i64
  • +
  • u64
  • +
  • i16
  • +
  • u16
  • +
+

Associated Types

type OutType: HasAfEnum

The type of Array object returned by generate function

+
Loading content...

Required methods

fn generate(&self, dims: Dim4) -> Array<Self::OutType>

Create an Array of dims size from scalar value self.

+

Parameters

+
    +
  • dims are the dimensions of the output constant Array
  • +
+
Loading content...

Implementations on Foreign Types

impl ConstGenerator for i64[src]

type OutType = i64

impl ConstGenerator for u64[src]

type OutType = u64

impl ConstGenerator for bool[src]

type OutType = bool

impl ConstGenerator for f32[src]

type OutType = f32

impl ConstGenerator for f64[src]

type OutType = f64

impl ConstGenerator for i32[src]

type OutType = i32

impl ConstGenerator for u32[src]

type OutType = u32

impl ConstGenerator for u8[src]

type OutType = u8

impl ConstGenerator for i16[src]

type OutType = i16

impl ConstGenerator for u16[src]

type OutType = u16

Loading content...

Implementors

impl ConstGenerator for c32[src]

type OutType = c32

impl ConstGenerator for c64[src]

type OutType = c64

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.Convertable.html b/arrayfire/trait.Convertable.html new file mode 100644 index 000000000..ba2b6b076 --- /dev/null +++ b/arrayfire/trait.Convertable.html @@ -0,0 +1,41 @@ +arrayfire::Convertable - Rust + + + +

[][src]Trait arrayfire::Convertable

pub trait Convertable {
+    type OutType: HasAfEnum;
+    fn convert(&self) -> Array<Self::OutType>;
+}

Type Trait to convert to an Array

+

Generic functions that overload the binary operations such as add, div, mul, rem, ge etc. are +bound by this trait to allow combinations of scalar values and Array objects as parameters +to those functions.

+

Internally, Convertable trait is implemented by following types.

+
    +
  • f32
  • +
  • f64
  • +
  • num::Complex<f32>
  • +
  • num::Complex<f64>
  • +
  • bool
  • +
  • i32
  • +
  • u32
  • +
  • u8
  • +
  • i64
  • +
  • u64
  • +
  • i16
  • +
  • u16
  • +
+

Associated Types

type OutType: HasAfEnum

This type alias always points to Self which is the +type of Array returned by the +trait method convert.

+
Loading content...

Required methods

fn convert(&self) -> Array<Self::OutType>

Get an Array of implementors type

+
Loading content...

Implementors

impl<T> Convertable for T where
    T: Clone + ConstGenerator<OutType = T>, 
[src]

type OutType = T

impl<T: HasAfEnum> Convertable for Array<T>[src]

type OutType = T

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.CovarianceComputable.html b/arrayfire/trait.CovarianceComputable.html new file mode 100644 index 000000000..53753fd9e --- /dev/null +++ b/arrayfire/trait.CovarianceComputable.html @@ -0,0 +1,16 @@ +arrayfire::CovarianceComputable - Rust + + + +

[][src]Trait arrayfire::CovarianceComputable

pub trait CovarianceComputable: HasAfEnum { }

Trait qualifier for given type indicating computability of covariance

+

Implementations on Foreign Types

impl CovarianceComputable for f64[src]

impl CovarianceComputable for f32[src]

impl CovarianceComputable for i32[src]

impl CovarianceComputable for u32[src]

impl CovarianceComputable for i16[src]

impl CovarianceComputable for u16[src]

impl CovarianceComputable for u8[src]

impl CovarianceComputable for u64[src]

impl CovarianceComputable for i64[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.DeconvInput.html b/arrayfire/trait.DeconvInput.html new file mode 100644 index 000000000..8f8fb16fd --- /dev/null +++ b/arrayfire/trait.DeconvInput.html @@ -0,0 +1,16 @@ +arrayfire::DeconvInput - Rust + + + +

[][src]Trait arrayfire::DeconvInput

pub trait DeconvInput: HasAfEnum { }

Trait qualifier for confidence connected components input

+

Implementations on Foreign Types

impl DeconvInput for f32[src]

impl DeconvInput for i16[src]

impl DeconvInput for u16[src]

impl DeconvInput for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.EdgeComputable.html b/arrayfire/trait.EdgeComputable.html new file mode 100644 index 000000000..12bb2b86b --- /dev/null +++ b/arrayfire/trait.EdgeComputable.html @@ -0,0 +1,17 @@ +arrayfire::EdgeComputable - Rust + + + +

[][src]Trait arrayfire::EdgeComputable

pub trait EdgeComputable: HasAfEnum { }

Trait qualifier for given type indicating if edge calculations such as +derivates etc. can be performed

+

Implementations on Foreign Types

impl EdgeComputable for f64[src]

impl EdgeComputable for f32[src]

impl EdgeComputable for i32[src]

impl EdgeComputable for u32[src]

impl EdgeComputable for i16[src]

impl EdgeComputable for u16[src]

impl EdgeComputable for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.FloatingPoint.html b/arrayfire/trait.FloatingPoint.html new file mode 100644 index 000000000..c89c17d56 --- /dev/null +++ b/arrayfire/trait.FloatingPoint.html @@ -0,0 +1,21 @@ +arrayfire::FloatingPoint - Rust + + + +

[][src]Trait arrayfire::FloatingPoint

pub trait FloatingPoint: HasAfEnum {
+    fn is_real() -> bool { ... }
+
fn is_complex() -> bool { ... } +}

Trait qualifier to accept either real or complex typed data

+

Provided methods

fn is_real() -> bool

Use to check if trait implementor is real number

+

fn is_complex() -> bool

Use to check if trait implementor is complex number

+
Loading content...

Implementations on Foreign Types

impl FloatingPoint for Complex<f64>[src]

impl FloatingPoint for Complex<f32>[src]

impl FloatingPoint for f64[src]

impl FloatingPoint for f32[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.Fromf64.html b/arrayfire/trait.Fromf64.html new file mode 100644 index 000000000..5b14a78b7 --- /dev/null +++ b/arrayfire/trait.Fromf64.html @@ -0,0 +1,20 @@ +arrayfire::Fromf64 - Rust + + + +

[][src]Trait arrayfire::Fromf64

pub trait Fromf64 {
+    fn fromf64(value: f64) -> Self;
+}

Trait to convert reduction's scalar output to appropriate output type

+

This is an internal trait and ideally of no use to user usecases.

+

Required methods

fn fromf64(value: f64) -> Self

Convert to target type from a double precision value

+
Loading content...

Implementations on Foreign Types

impl Fromf64 for usize[src]

impl Fromf64 for f64[src]

impl Fromf64 for u64[src]

impl Fromf64 for i64[src]

impl Fromf64 for f32[src]

impl Fromf64 for u32[src]

impl Fromf64 for i32[src]

impl Fromf64 for u16[src]

impl Fromf64 for i16[src]

impl Fromf64 for u8[src]

impl Fromf64 for bool[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.GrayRGBConvertible.html b/arrayfire/trait.GrayRGBConvertible.html new file mode 100644 index 000000000..bce63a254 --- /dev/null +++ b/arrayfire/trait.GrayRGBConvertible.html @@ -0,0 +1,17 @@ +arrayfire::GrayRGBConvertible - Rust + + + +

[][src]Trait arrayfire::GrayRGBConvertible

pub trait GrayRGBConvertible: HasAfEnum { }

Trait qualifier for given type indicating conversion capability between +grayscale and RGB triplets of data

+

Implementations on Foreign Types

impl GrayRGBConvertible for f64[src]

impl GrayRGBConvertible for f32[src]

impl GrayRGBConvertible for i32[src]

impl GrayRGBConvertible for u32[src]

impl GrayRGBConvertible for i16[src]

impl GrayRGBConvertible for u16[src]

impl GrayRGBConvertible for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.HasAfEnum.html b/arrayfire/trait.HasAfEnum.html new file mode 100644 index 000000000..beff4f09b --- /dev/null +++ b/arrayfire/trait.HasAfEnum.html @@ -0,0 +1,84 @@ +arrayfire::HasAfEnum - Rust + + + +

[][src]Trait arrayfire::HasAfEnum

pub trait HasAfEnum {
+    type InType: HasAfEnum;
+    type BaseType: HasAfEnum;
+    type AbsOutType: HasAfEnum;
+    type ArgOutType: HasAfEnum;
+    type UnaryOutType: HasAfEnum;
+    type ComplexOutType;
+    type MeanOutType: HasAfEnum;
+    type AggregateOutType: HasAfEnum;
+    type ProductOutType: HasAfEnum;
+    type SobelOutType: HasAfEnum;
+    fn get_af_dtype() -> DType;
+}

Types of the data that can be generated using ArrayFire data generation functions.

+

The trait HasAfEnum has been defined internally for the following types. We strongly suggest +not to implement this trait in your program for user defined types because ArrayFire functions +will only work for the following data types currently. Any such trait implementation for types +other than the ones listed below will result in undefined behavior.

+
    +
  • f32
  • +
  • f64
  • +
  • num::Complex<f32>
  • +
  • num::Complex<f64>
  • +
  • bool
  • +
  • i32
  • +
  • u32
  • +
  • u8
  • +
  • i64
  • +
  • u64
  • +
  • i16
  • +
  • u16
  • +
+

Associated Types

type InType: HasAfEnum

This type alias points to Self always.

+

type BaseType: HasAfEnum

This type alias points to the data type used to hold real part of a +complex number. For real valued numbers, this points to Self.

+

type AbsOutType: HasAfEnum

This type alias points to f32 for all 32 bit size types and f64 for +larger 64-bit size types.

+

type ArgOutType: HasAfEnum

This type alias points to f64/f32 for floating point types and +Self otherwise.

+

type UnaryOutType: HasAfEnum

This type alias is used to define the output Array type for unary +operations. It points to Self for floating point types, either +real or complex. It points to f32 for rest of the input types.

+

type ComplexOutType

This type alias points to complex type created from a given input type. +This alias always points to either std::Complex<f32> or std::Complex<f64>

+

type MeanOutType: HasAfEnum

This type alias points to a data type that can store the mean value for +a given input type. This alias points to f32/Complex<f32> for all 32 +bit size types and f64/Complex<f64> for larger 64-bit size types.

+

type AggregateOutType: HasAfEnum

This type alias points to a data type that can store the result of +aggregation of set of values for a given input type. Aggregate type +alias points to below types for given input types:

+
    +
  • Self for input types: Complex<64>, Complex<f32>, f64, f32, i64, u64
  • +
  • u32 for input types: bool
  • +
  • u32 for input types: u8
  • +
  • i32 for input types: i16
  • +
  • u32 for input types: u16
  • +
  • i32 for input types: i32
  • +
  • u32 for input types: u32
  • +
+

type ProductOutType: HasAfEnum

This type is different for b8 input type

+

type SobelOutType: HasAfEnum

This type alias points to the output type for given input type of +sobel filter operation. Sobel filter output alias points to below +types for given input types:

+
    +
  • f32 for input types: Complex<f32>, f32
  • +
  • f64 for input types: Complex<f64>, f64
  • +
  • i32 for input types: bool, u8, i16, u16, i32, u32
  • +
  • i64 for input types: i64, u64
  • +
+
Loading content...

Required methods

fn get_af_dtype() -> DType

Return trait implmentors corresponding DType

+
Loading content...

Implementations on Foreign Types

impl HasAfEnum for Complex<f32>[src]

type InType = Self

type BaseType = f32

type AbsOutType = f32

type ArgOutType = f32

type UnaryOutType = Self

type ComplexOutType = Self

type MeanOutType = Self

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = Self

impl HasAfEnum for Complex<f64>[src]

type InType = Self

type BaseType = f64

type AbsOutType = f64

type ArgOutType = f64

type UnaryOutType = Self

type ComplexOutType = Self

type MeanOutType = Self

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = Self

impl HasAfEnum for f32[src]

type InType = Self

type BaseType = Self

type AbsOutType = f32

type ArgOutType = f32

type UnaryOutType = Self

type ComplexOutType = Complex<f32>

type MeanOutType = Self

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = Self

impl HasAfEnum for f64[src]

type InType = Self

type BaseType = Self

type AbsOutType = f64

type ArgOutType = f64

type UnaryOutType = Self

type ComplexOutType = Complex<f64>

type MeanOutType = Self

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = Self

impl HasAfEnum for bool[src]

impl HasAfEnum for u8[src]

impl HasAfEnum for i16[src]

impl HasAfEnum for u16[src]

impl HasAfEnum for f16[src]

type InType = Self

type BaseType = Self

type AbsOutType = Self

type ArgOutType = Self

type UnaryOutType = Self

type ComplexOutType = Complex<f16>

type MeanOutType = Self

type AggregateOutType = f32

type ProductOutType = f32

type SobelOutType = Self

impl HasAfEnum for i32[src]

impl HasAfEnum for u32[src]

impl HasAfEnum for i64[src]

type InType = Self

type BaseType = Self

type AbsOutType = f64

type ArgOutType = i64

type UnaryOutType = f64

type ComplexOutType = Complex<f64>

type MeanOutType = f64

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = i64

impl HasAfEnum for u64[src]

type InType = Self

type BaseType = Self

type AbsOutType = f64

type ArgOutType = u64

type UnaryOutType = f64

type ComplexOutType = Complex<f64>

type MeanOutType = f64

type AggregateOutType = Self

type ProductOutType = Self

type SobelOutType = i64

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ImageFilterType.html b/arrayfire/trait.ImageFilterType.html new file mode 100644 index 000000000..f4ea5716e --- /dev/null +++ b/arrayfire/trait.ImageFilterType.html @@ -0,0 +1,17 @@ +arrayfire::ImageFilterType - Rust + + + +

[][src]Trait arrayfire::ImageFilterType

pub trait ImageFilterType: HasAfEnum { }

Trait qualifier for type of Array's that are accepted +by image processing functions especially filtering algorithms

+

Implementations on Foreign Types

impl ImageFilterType for f64[src]

impl ImageFilterType for f32[src]

impl ImageFilterType for i32[src]

impl ImageFilterType for u32[src]

impl ImageFilterType for i16[src]

impl ImageFilterType for u16[src]

impl ImageFilterType for u8[src]

impl ImageFilterType for bool[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ImageNativeType.html b/arrayfire/trait.ImageNativeType.html new file mode 100644 index 000000000..b60358fe5 --- /dev/null +++ b/arrayfire/trait.ImageNativeType.html @@ -0,0 +1,17 @@ +arrayfire::ImageNativeType - Rust + + + +

[][src]Trait arrayfire::ImageNativeType

pub trait ImageNativeType: HasAfEnum { }

Trait qualifier for type of Array's that are accepted +by native image load/save functions.

+

Implementations on Foreign Types

impl ImageNativeType for f32[src]

impl ImageNativeType for u16[src]

impl ImageNativeType for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ImplicitPromote.html b/arrayfire/trait.ImplicitPromote.html new file mode 100644 index 000000000..dafedfae1 --- /dev/null +++ b/arrayfire/trait.ImplicitPromote.html @@ -0,0 +1,22 @@ +arrayfire::ImplicitPromote - Rust + + + +

[][src]Trait arrayfire::ImplicitPromote

pub trait ImplicitPromote<RHS>: HasAfEnum {
+    type Output: HasAfEnum;
+}

This is an internal trait defined and implemented by ArrayFire +create for rust's built-in types to figure out the data type +binary operation's results.

+

Associated Types

type Output: HasAfEnum

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS.

+
Loading content...

Implementations on Foreign Types

impl ImplicitPromote<Complex<f64>> for f64[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for f64[src]

type Output = c64

impl ImplicitPromote<f32> for f64[src]

type Output = f64

impl ImplicitPromote<i64> for f64[src]

type Output = f64

impl ImplicitPromote<u64> for f64[src]

type Output = f64

impl ImplicitPromote<i32> for f64[src]

type Output = f64

impl ImplicitPromote<u32> for f64[src]

type Output = f64

impl ImplicitPromote<i16> for f64[src]

type Output = f64

impl ImplicitPromote<u16> for f64[src]

type Output = f64

impl ImplicitPromote<bool> for f64[src]

type Output = f64

impl ImplicitPromote<u8> for f64[src]

type Output = f64

impl ImplicitPromote<Complex<f64>> for f32[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for f32[src]

type Output = c32

impl ImplicitPromote<f64> for f32[src]

type Output = f64

impl ImplicitPromote<i64> for f32[src]

type Output = f32

impl ImplicitPromote<u64> for f32[src]

type Output = f32

impl ImplicitPromote<i32> for f32[src]

type Output = f32

impl ImplicitPromote<u32> for f32[src]

type Output = f32

impl ImplicitPromote<i16> for f32[src]

type Output = f32

impl ImplicitPromote<u16> for f32[src]

type Output = f32

impl ImplicitPromote<bool> for f32[src]

type Output = f32

impl ImplicitPromote<u8> for f32[src]

type Output = f32

impl ImplicitPromote<Complex<f64>> for i64[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for i64[src]

type Output = c32

impl ImplicitPromote<f64> for i64[src]

type Output = f64

impl ImplicitPromote<f32> for i64[src]

type Output = f32

impl ImplicitPromote<u64> for i64[src]

type Output = u64

impl ImplicitPromote<i32> for i64[src]

type Output = i64

impl ImplicitPromote<u32> for i64[src]

type Output = i64

impl ImplicitPromote<i16> for i64[src]

type Output = i64

impl ImplicitPromote<u16> for i64[src]

type Output = i64

impl ImplicitPromote<bool> for i64[src]

type Output = i64

impl ImplicitPromote<u8> for i64[src]

type Output = i64

impl ImplicitPromote<Complex<f64>> for u64[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for u64[src]

type Output = c32

impl ImplicitPromote<f64> for u64[src]

type Output = f64

impl ImplicitPromote<f32> for u64[src]

type Output = f32

impl ImplicitPromote<i64> for u64[src]

type Output = u64

impl ImplicitPromote<i32> for u64[src]

type Output = u64

impl ImplicitPromote<u32> for u64[src]

type Output = u64

impl ImplicitPromote<i16> for u64[src]

type Output = u64

impl ImplicitPromote<u16> for u64[src]

type Output = u64

impl ImplicitPromote<bool> for u64[src]

type Output = u64

impl ImplicitPromote<u8> for u64[src]

type Output = u64

impl ImplicitPromote<Complex<f64>> for i32[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for i32[src]

type Output = c32

impl ImplicitPromote<f64> for i32[src]

type Output = f64

impl ImplicitPromote<f32> for i32[src]

type Output = f32

impl ImplicitPromote<i64> for i32[src]

type Output = i64

impl ImplicitPromote<u64> for i32[src]

type Output = u64

impl ImplicitPromote<u32> for i32[src]

type Output = u32

impl ImplicitPromote<i16> for i32[src]

type Output = i32

impl ImplicitPromote<u16> for i32[src]

type Output = i32

impl ImplicitPromote<bool> for i32[src]

type Output = i32

impl ImplicitPromote<u8> for i32[src]

type Output = i32

impl ImplicitPromote<Complex<f64>> for u32[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for u32[src]

type Output = c32

impl ImplicitPromote<f64> for u32[src]

type Output = f64

impl ImplicitPromote<f32> for u32[src]

type Output = f32

impl ImplicitPromote<i64> for u32[src]

type Output = i64

impl ImplicitPromote<u64> for u32[src]

type Output = u64

impl ImplicitPromote<i32> for u32[src]

type Output = u32

impl ImplicitPromote<i16> for u32[src]

type Output = u32

impl ImplicitPromote<u16> for u32[src]

type Output = u32

impl ImplicitPromote<bool> for u32[src]

type Output = u32

impl ImplicitPromote<u8> for u32[src]

type Output = u32

impl ImplicitPromote<Complex<f64>> for i16[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for i16[src]

type Output = c32

impl ImplicitPromote<f64> for i16[src]

type Output = f64

impl ImplicitPromote<f32> for i16[src]

type Output = f32

impl ImplicitPromote<i64> for i16[src]

type Output = i64

impl ImplicitPromote<u64> for i16[src]

type Output = u64

impl ImplicitPromote<i32> for i16[src]

type Output = i32

impl ImplicitPromote<u32> for i16[src]

type Output = u32

impl ImplicitPromote<u16> for i16[src]

type Output = u16

impl ImplicitPromote<bool> for i16[src]

type Output = u16

impl ImplicitPromote<u8> for i16[src]

type Output = u16

impl ImplicitPromote<Complex<f64>> for u16[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for u16[src]

type Output = c32

impl ImplicitPromote<f64> for u16[src]

type Output = f64

impl ImplicitPromote<f32> for u16[src]

type Output = f32

impl ImplicitPromote<i64> for u16[src]

type Output = i64

impl ImplicitPromote<u64> for u16[src]

type Output = u64

impl ImplicitPromote<i32> for u16[src]

type Output = i32

impl ImplicitPromote<u32> for u16[src]

type Output = u32

impl ImplicitPromote<i16> for u16[src]

type Output = u16

impl ImplicitPromote<bool> for u16[src]

type Output = u16

impl ImplicitPromote<u8> for u16[src]

type Output = u16

impl ImplicitPromote<Complex<f64>> for u8[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for u8[src]

type Output = c32

impl ImplicitPromote<f64> for u8[src]

type Output = f64

impl ImplicitPromote<f32> for u8[src]

type Output = f32

impl ImplicitPromote<i64> for u8[src]

type Output = i64

impl ImplicitPromote<u64> for u8[src]

type Output = u64

impl ImplicitPromote<i32> for u8[src]

type Output = i32

impl ImplicitPromote<u32> for u8[src]

type Output = u32

impl ImplicitPromote<i16> for u8[src]

type Output = i16

impl ImplicitPromote<u16> for u8[src]

type Output = u16

impl ImplicitPromote<bool> for u8[src]

type Output = u8

impl ImplicitPromote<Complex<f64>> for bool[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for bool[src]

type Output = c32

impl ImplicitPromote<f64> for bool[src]

type Output = f64

impl ImplicitPromote<f32> for bool[src]

type Output = f32

impl ImplicitPromote<i64> for bool[src]

type Output = i64

impl ImplicitPromote<u64> for bool[src]

type Output = u64

impl ImplicitPromote<i32> for bool[src]

type Output = i32

impl ImplicitPromote<u32> for bool[src]

type Output = u32

impl ImplicitPromote<i16> for bool[src]

type Output = i16

impl ImplicitPromote<u16> for bool[src]

type Output = u16

impl ImplicitPromote<u8> for bool[src]

type Output = u8

Loading content...

Implementors

impl ImplicitPromote<bool> for c32[src]

type Output = c32

impl ImplicitPromote<bool> for c64[src]

type Output = c64

impl ImplicitPromote<f32> for c32[src]

type Output = c32

impl ImplicitPromote<f32> for c64[src]

type Output = c64

impl ImplicitPromote<f64> for c32[src]

type Output = c64

impl ImplicitPromote<f64> for c64[src]

type Output = c64

impl ImplicitPromote<i16> for c32[src]

type Output = c32

impl ImplicitPromote<i16> for c64[src]

type Output = c64

impl ImplicitPromote<i32> for c32[src]

type Output = c32

impl ImplicitPromote<i32> for c64[src]

type Output = c64

impl ImplicitPromote<i64> for c32[src]

type Output = c32

impl ImplicitPromote<i64> for c64[src]

type Output = c64

impl ImplicitPromote<u8> for c32[src]

type Output = c32

impl ImplicitPromote<u8> for c64[src]

type Output = c64

impl ImplicitPromote<u16> for c32[src]

type Output = c32

impl ImplicitPromote<u16> for c64[src]

type Output = c64

impl ImplicitPromote<u32> for c32[src]

type Output = c32

impl ImplicitPromote<u32> for c64[src]

type Output = c64

impl ImplicitPromote<u64> for c32[src]

type Output = c32

impl ImplicitPromote<u64> for c64[src]

type Output = c64

impl ImplicitPromote<Complex<f32>> for c64[src]

type Output = c64

impl ImplicitPromote<Complex<f64>> for c32[src]

type Output = c64

impl<T> ImplicitPromote<T> for T where
    T: HasAfEnum
[src]

type Output = T

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.Indexable.html b/arrayfire/trait.Indexable.html new file mode 100644 index 000000000..b08d1a7ba --- /dev/null +++ b/arrayfire/trait.Indexable.html @@ -0,0 +1,40 @@ +arrayfire::Indexable - Rust + + + +

[][src]Trait arrayfire::Indexable

pub trait Indexable {
+    fn set(&self, idxr: &mut Indexer<'_>, dim: u32, is_batch: Option<bool>);
+}

Trait bound indicating indexability

+

Any object to be able to be passed on to Indexer::set_index() method should implement this trait with appropriate implementation of set method.

+

Required methods

fn set(&self, idxr: &mut Indexer<'_>, dim: u32, is_batch: Option<bool>)

Set indexing object for a given dimension

+

is_batch parameter is not used in most cases as it has been provided in +ArrayFire C-API to enable GFOR construct in ArrayFire C++ API. This type +of construct/idea is not exposed in rust wrapper yet. So, the user would +just need to pass None to this parameter while calling this function. +Since we can't have default default values and we wanted to keep this +parameter for future use cases, we just made it an std::Option.

+

Parameters

+
    +
  • idxr is mutable reference to Indexer object which will +be modified to set self indexable along dim dimension.
  • +
  • dim is the dimension along which self indexable will be used for indexing.
  • +
  • is_batch is only used if self is Seq to indicate if indexing +along dim is a batched operation.
  • +
+
Loading content...

Implementors

impl<T> Indexable for Array<T> where
    T: HasAfEnum + IndexableType
[src]

Enables Array to be used to index another Array

+

This is used in functions index_gen and +assign_gen

+

impl<T> Indexable for Seq<T> where
    c_double: From<T>,
    T: Copy + IndexableType
[src]

Enables Seq to be used to index another Array

+

This is used in functions index_gen and +assign_gen

+
Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.IndexableType.html b/arrayfire/trait.IndexableType.html new file mode 100644 index 000000000..8a42b91db --- /dev/null +++ b/arrayfire/trait.IndexableType.html @@ -0,0 +1,16 @@ +arrayfire::IndexableType - Rust + + + +

[][src]Trait arrayfire::IndexableType

pub trait IndexableType: HasAfEnum { }

Trait qualifier for the type of Arrays accepted by scan operations

+

Implementations on Foreign Types

impl IndexableType for f64[src]

impl IndexableType for i64[src]

impl IndexableType for u64[src]

impl IndexableType for f32[src]

impl IndexableType for i32[src]

impl IndexableType for u32[src]

impl IndexableType for i16[src]

impl IndexableType for u16[src]

impl IndexableType for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.IntegralType.html b/arrayfire/trait.IntegralType.html new file mode 100644 index 000000000..1808d074a --- /dev/null +++ b/arrayfire/trait.IntegralType.html @@ -0,0 +1,16 @@ +arrayfire::IntegralType - Rust + + + +

[][src]Trait arrayfire::IntegralType

pub trait IntegralType { }

Trait qualifier for given type indicating computability of covariance

+

Implementations on Foreign Types

impl IntegralType for i64[src]

impl IntegralType for u64[src]

impl IntegralType for i32[src]

impl IntegralType for u32[src]

impl IntegralType for i16[src]

impl IntegralType for u16[src]

impl IntegralType for u8[src]

impl IntegralType for bool[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.MedianComputable.html b/arrayfire/trait.MedianComputable.html new file mode 100644 index 000000000..1f9fc2da7 --- /dev/null +++ b/arrayfire/trait.MedianComputable.html @@ -0,0 +1,16 @@ +arrayfire::MedianComputable - Rust + + + +

[][src]Trait arrayfire::MedianComputable

pub trait MedianComputable: HasAfEnum { }

Trait qualifier for given type indicating computability of Median

+

Implementations on Foreign Types

impl MedianComputable for f64[src]

impl MedianComputable for f32[src]

impl MedianComputable for i32[src]

impl MedianComputable for u32[src]

impl MedianComputable for i16[src]

impl MedianComputable for u16[src]

impl MedianComputable for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.MomentsComputable.html b/arrayfire/trait.MomentsComputable.html new file mode 100644 index 000000000..929977927 --- /dev/null +++ b/arrayfire/trait.MomentsComputable.html @@ -0,0 +1,16 @@ +arrayfire::MomentsComputable - Rust + + + +

[][src]Trait arrayfire::MomentsComputable

pub trait MomentsComputable: HasAfEnum { }

Trait qualifier for given type indicating computability of Moments

+

Implementations on Foreign Types

impl MomentsComputable for f64[src]

impl MomentsComputable for f32[src]

impl MomentsComputable for i32[src]

impl MomentsComputable for u32[src]

impl MomentsComputable for i16[src]

impl MomentsComputable for u16[src]

impl MomentsComputable for u8[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.RealFloating.html b/arrayfire/trait.RealFloating.html new file mode 100644 index 000000000..556402a3e --- /dev/null +++ b/arrayfire/trait.RealFloating.html @@ -0,0 +1,16 @@ +arrayfire::RealFloating - Rust + + + +

[][src]Trait arrayfire::RealFloating

pub trait RealFloating: HasAfEnum { }

Trait qualifier to accept real data(numbers)

+

Implementations on Foreign Types

impl RealFloating for f64[src]

impl RealFloating for f32[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.RealNumber.html b/arrayfire/trait.RealNumber.html new file mode 100644 index 000000000..2aa651a4a --- /dev/null +++ b/arrayfire/trait.RealNumber.html @@ -0,0 +1,16 @@ +arrayfire::RealNumber - Rust + + + +

[][src]Trait arrayfire::RealNumber

pub trait RealNumber: HasAfEnum { }

Trait qualifier indicating it can hold real numbers only

+

Implementations on Foreign Types

impl RealNumber for f64[src]

impl RealNumber for f32[src]

impl RealNumber for i32[src]

impl RealNumber for u32[src]

impl RealNumber for i16[src]

impl RealNumber for u16[src]

impl RealNumber for u8[src]

impl RealNumber for bool[src]

impl RealNumber for u64[src]

impl RealNumber for i64[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.ReduceByKeyInput.html b/arrayfire/trait.ReduceByKeyInput.html new file mode 100644 index 000000000..32c12b5b3 --- /dev/null +++ b/arrayfire/trait.ReduceByKeyInput.html @@ -0,0 +1,16 @@ +arrayfire::ReduceByKeyInput - Rust + + + +

[][src]Trait arrayfire::ReduceByKeyInput

pub trait ReduceByKeyInput: HasAfEnum { }

Trait qualifier for Reduction Key type

+

Implementations on Foreign Types

impl ReduceByKeyInput for i32[src]

impl ReduceByKeyInput for u32[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/trait.Scanable.html b/arrayfire/trait.Scanable.html new file mode 100644 index 000000000..cb405fd59 --- /dev/null +++ b/arrayfire/trait.Scanable.html @@ -0,0 +1,16 @@ +arrayfire::Scanable - Rust + + + +

[][src]Trait arrayfire::Scanable

pub trait Scanable: HasAfEnum { }

Trait qualifier for the type of Arrays accepted by scan operations

+

Implementations on Foreign Types

impl Scanable for i32[src]

impl Scanable for u32[src]

impl Scanable for u64[src]

impl Scanable for i64[src]

Loading content...

Implementors

Loading content...
\ No newline at end of file diff --git a/arrayfire/type.ErrorCallback.html b/arrayfire/type.ErrorCallback.html new file mode 100644 index 000000000..544c42054 --- /dev/null +++ b/arrayfire/type.ErrorCallback.html @@ -0,0 +1,16 @@ +arrayfire::ErrorCallback - Rust + + + +

[][src]Type Definition arrayfire::ErrorCallback

type ErrorCallback = fn(_: AfError);

Signature of error handling callback function

+
\ No newline at end of file diff --git a/arrayfire/type.af_array.html b/arrayfire/type.af_array.html new file mode 100644 index 000000000..23e9b9fb2 --- /dev/null +++ b/arrayfire/type.af_array.html @@ -0,0 +1,19 @@ +arrayfire::af_array - Rust + + + +

[][src]Type Definition arrayfire::af_array

type af_array = *mut c_void;

ArrayFire FFI Type alias for af_array

+

Trait Implementations

impl<T: HasAfEnum> Into<Array<T>> for af_array[src]

Used for creating Array object from native +resource id, an 64 bit integer

+
\ No newline at end of file diff --git a/arrayfire/type.af_event.html b/arrayfire/type.af_event.html new file mode 100644 index 000000000..b1c6e4ef3 --- /dev/null +++ b/arrayfire/type.af_event.html @@ -0,0 +1,16 @@ +arrayfire::af_event - Rust + + + +

[][src]Type Definition arrayfire::af_event

type af_event = *mut c_void;

ArrayFire FFI Type alias for af_event

+
\ No newline at end of file diff --git a/arrayfire/type.af_features.html b/arrayfire/type.af_features.html new file mode 100644 index 000000000..25e645a7f --- /dev/null +++ b/arrayfire/type.af_features.html @@ -0,0 +1,16 @@ +arrayfire::af_features - Rust + + + +

[][src]Type Definition arrayfire::af_features

type af_features = *const c_void;

ArrayFire FFI Type alias for af_features

+
\ No newline at end of file diff --git a/arrayfire/type.af_index_t.html b/arrayfire/type.af_index_t.html new file mode 100644 index 000000000..27795a88e --- /dev/null +++ b/arrayfire/type.af_index_t.html @@ -0,0 +1,16 @@ +arrayfire::af_index_t - Rust + + + +

[][src]Type Definition arrayfire::af_index_t

type af_index_t = *mut c_void;

ArrayFire FFI Type alias for af_indexers_t

+
\ No newline at end of file diff --git a/arrayfire/type.af_random_engine.html b/arrayfire/type.af_random_engine.html new file mode 100644 index 000000000..417249cfb --- /dev/null +++ b/arrayfire/type.af_random_engine.html @@ -0,0 +1,16 @@ +arrayfire::af_random_engine - Rust + + + +

[][src]Type Definition arrayfire::af_random_engine

type af_random_engine = *mut c_void;

ArrayFire FFI Type alias for af_random_engine

+
\ No newline at end of file diff --git a/arrayfire/type.af_window.html b/arrayfire/type.af_window.html new file mode 100644 index 000000000..fd7b6c849 --- /dev/null +++ b/arrayfire/type.af_window.html @@ -0,0 +1,16 @@ +arrayfire::af_window - Rust + + + +

[][src]Type Definition arrayfire::af_window

type af_window = *mut c_void;

ArrayFire FFI Type alias for af_window

+
\ No newline at end of file diff --git a/arrayfire/type.c32.html b/arrayfire/type.c32.html new file mode 100644 index 000000000..f8dbf4615 --- /dev/null +++ b/arrayfire/type.c32.html @@ -0,0 +1,40 @@ +arrayfire::c32 - Rust + + + +

[][src]Type Definition arrayfire::c32

type c32 = Complex<f32>;

Short type alias for Complex single precision type

+

Trait Implementations

impl ComplexFloating for c32[src]

impl ConstGenerator for c32[src]

type OutType = c32

The type of Array object returned by generate function

+

impl ImplicitPromote<Complex<f64>> for c32[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<bool> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<f32> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<f64> for c32[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i16> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i32> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i64> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u16> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u32> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u64> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u8> for c32[src]

type Output = c32

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+
\ No newline at end of file diff --git a/arrayfire/type.c64.html b/arrayfire/type.c64.html new file mode 100644 index 000000000..c2ce166a6 --- /dev/null +++ b/arrayfire/type.c64.html @@ -0,0 +1,40 @@ +arrayfire::c64 - Rust + + + +

[][src]Type Definition arrayfire::c64

type c64 = Complex<f64>;

Short type alias for Complex double precision type

+

Trait Implementations

impl ComplexFloating for c64[src]

impl ConstGenerator for c64[src]

type OutType = c64

The type of Array object returned by generate function

+

impl ImplicitPromote<Complex<f32>> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<bool> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<f32> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<f64> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i16> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i32> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<i64> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u16> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u32> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u64> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+

impl ImplicitPromote<u8> for c64[src]

type Output = c64

This type alias points to the type of the result obtained +by performing a given binary option on given type and RHS. Read more

+
\ No newline at end of file diff --git a/arrayfire/type.dim_t.html b/arrayfire/type.dim_t.html new file mode 100644 index 000000000..d2801cf8c --- /dev/null +++ b/arrayfire/type.dim_t.html @@ -0,0 +1,16 @@ +arrayfire::dim_t - Rust + + + +

[][src]Type Definition arrayfire::dim_t

type dim_t = c_longlong;

ArrayFire FFI Type alias for libc's signed long long

+
\ No newline at end of file diff --git a/arrayfire/type.u64_t.html b/arrayfire/type.u64_t.html new file mode 100644 index 000000000..623d26909 --- /dev/null +++ b/arrayfire/type.u64_t.html @@ -0,0 +1,16 @@ +arrayfire::u64_t - Rust + + + +

[][src]Type Definition arrayfire::u64_t

type u64_t = c_ulonglong;

ArrayFire FFI Type alias for libc's unsigned long long

+
\ No newline at end of file diff --git a/arrayfire/type.void_ptr.html b/arrayfire/type.void_ptr.html new file mode 100644 index 000000000..0a41a4857 --- /dev/null +++ b/arrayfire/type.void_ptr.html @@ -0,0 +1,16 @@ +arrayfire::void_ptr - Rust + + + +

[][src]Type Definition arrayfire::void_ptr

type void_ptr = *mut c_void;

ArrayFire FFI Type alias for libc's void*

+
\ No newline at end of file diff --git a/arrayfire/vision/fn.dog.html b/arrayfire/vision/fn.dog.html new file mode 100644 index 000000000..de38b6745 --- /dev/null +++ b/arrayfire/vision/fn.dog.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.dog.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.fast.html b/arrayfire/vision/fn.fast.html new file mode 100644 index 000000000..6bcb1261d --- /dev/null +++ b/arrayfire/vision/fn.fast.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.fast.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.hamming_matcher.html b/arrayfire/vision/fn.hamming_matcher.html new file mode 100644 index 000000000..98694a12c --- /dev/null +++ b/arrayfire/vision/fn.hamming_matcher.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.hamming_matcher.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.harris.html b/arrayfire/vision/fn.harris.html new file mode 100644 index 000000000..8001809d6 --- /dev/null +++ b/arrayfire/vision/fn.harris.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.harris.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.homography.html b/arrayfire/vision/fn.homography.html new file mode 100644 index 000000000..d7ad6c1d7 --- /dev/null +++ b/arrayfire/vision/fn.homography.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.homography.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.match_template.html b/arrayfire/vision/fn.match_template.html new file mode 100644 index 000000000..738509a8c --- /dev/null +++ b/arrayfire/vision/fn.match_template.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.match_template.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.nearest_neighbour.html b/arrayfire/vision/fn.nearest_neighbour.html new file mode 100644 index 000000000..92876f939 --- /dev/null +++ b/arrayfire/vision/fn.nearest_neighbour.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.nearest_neighbour.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.orb.html b/arrayfire/vision/fn.orb.html new file mode 100644 index 000000000..4c4b197e1 --- /dev/null +++ b/arrayfire/vision/fn.orb.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.orb.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/fn.susan.html b/arrayfire/vision/fn.susan.html new file mode 100644 index 000000000..de5dba09a --- /dev/null +++ b/arrayfire/vision/fn.susan.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/fn.susan.html...

+ + + \ No newline at end of file diff --git a/arrayfire/vision/struct.Features.html b/arrayfire/vision/struct.Features.html new file mode 100644 index 000000000..01104b6b4 --- /dev/null +++ b/arrayfire/vision/struct.Features.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../arrayfire/struct.Features.html...

+ + + \ No newline at end of file diff --git a/ayu.css b/ayu.css new file mode 100644 index 000000000..88b5428aa --- /dev/null +++ b/ayu.css @@ -0,0 +1 @@ + body{background-color:#0f1419;color:#c5c5c5;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:white;}h1.fqn{border-bottom-color:#5c6773;}h1.fqn a{color:#fff;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod){border-bottom-color:#5c6773;}h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border:none;}.in-band{background-color:#0f1419;}.invisible{background:rgba(0,0,0,0);}code{color:#ffb454;}h3>code,h4>code,h5>code{color:#e6e1cf;}pre>code{color:#e6e1cf;}span code{color:#e6e1cf;}.docblock a>code{color:#39AFD7 !important;}.docblock code,.docblock-short code{background-color:#191f26;}pre{color:#e6e1cf;background-color:#191f26;}.sidebar{background-color:#14191f;}.logo-container.rust-logo>img{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);}*{scrollbar-color:#5c6773 transparent;}.sidebar{scrollbar-color:#5c6773 transparent;}::-webkit-scrollbar-track{background-color:transparent;}::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar::-webkit-scrollbar-track{background-color:transparent;}.sidebar::-webkit-scrollbar-thumb{background-color:#5c6773;}.sidebar .current{background-color:transparent;color:#ffb44c;}.source .sidebar{background-color:#0f1419;}.sidebar .location{border-color:#000;background-color:#0f1419;color:#fff;}.sidebar-elems .location{color:#ff7733;}.sidebar-elems .location a{color:#fff;}.sidebar .version{border-bottom-color:#424c57;}.sidebar-title{border-top-color:#5c6773;border-bottom-color:#5c6773;}.block a:hover{background:transparent;color:#ffb44c;}.line-numbers span{color:#5c6773;}.line-numbers .line-highlighted{color:#708090;background-color:rgba(255,236,164,0.06);padding-right:4px;border-right:1px solid #ffb44c;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#5c6773;}.docblock table,.docblock table td,.docblock table th{border-color:#5c6773;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#c5c5c5;}.content .highlighted{color:#000 !important;background-color:#c6afb3;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted{background-color:#c6afb3;}.search-results a{color:#0096cf;}.search-results a span.desc{color:#c5c5c5;}.content .stability::before{color:#ccc;}.content span.foreigntype,.content a.foreigntype{color:#ef57ff;}.content span.union,.content a.union{color:#98a01c;}.content span.constant,.content a.constant,.content span.static,.content a.static{color:#6380a0;}.content span.primitive,.content a.primitive{color:#32889b;}.content span.traitalias,.content a.traitalias{color:#57d399;}.content span.keyword,.content a.keyword{color:#de5249;}.content span.externcrate,.content span.mod,.content a.mod{color:#acccf9;}.content span.struct,.content a.struct{color:#ffa0a5;}.content span.enum,.content a.enum{color:#99e0c9;}.content span.trait,.content a.trait{color:#39AFD7;}.content span.type,.content a.type{color:#cfbcf5;}.content span.fn,.content a.fn,.content span.method,.content a.method,.content span.tymethod,.content a.tymethod,.content .fnname{color:#fdd687;}.content span.attr,.content a.attr,.content span.derive,.content a.derive,.content span.macro,.content a.macro{color:#a37acc;}pre.rust .comment{color:#788797;}pre.rust .doccomment{color:#a1ac88;}nav:not(.sidebar){border-bottom-color:#424c57;}nav.main .current{border-top-color:#5c6773;border-bottom-color:#5c6773;}nav.main .separator{border:1px solid #5c6773;}a{color:#c5c5c5;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a,#help a{color:#39AFD7;}.collapse-toggle{color:#999;}#crate-search{color:#c5c5c5;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;border-color:#424c57;}.search-input{color:#ffffff;background-color:#141920;box-shadow:0 0 0 1px #424c57,0 0 0 2px transparent;transition:box-shadow 150ms ease-in-out;}#crate-search+.search-input:focus{box-shadow:0 0 0 1px #148099,0 0 0 2px transparent;}.search-focus:disabled{color:#929292;}.module-item .stab{color:#000;}.stab.unstable,.stab.deprecated,.stab.portability{color:#c5c5c5;background:#314559 !important;border-style:none !important;border-radius:4px;padding:3px 6px 3px 6px;}.stab.portability>code{color:#e6e1cf;background-color:transparent;}#help>div{background:#14191f;box-shadow:0px 6px 20px 0px black;border:none;border-radius:4px;}#help>div>span{border-bottom-color:#5c6773;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#788797;}.line-numbers :target{background-color:transparent;}pre.rust .number,pre.rust .string{color:#b8cc52;}pre.rust .kw,pre.rust .kw-2,pre.rust .prelude-ty,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .op,pre.rust .lifetime{color:#ff7733;}pre.rust .macro,pre.rust .macro-nonterminal{color:#a37acc;}pre.rust .question-mark{color:#ff9011;}pre.rust .self{color:#36a3d9;font-style:italic;}pre.rust .attribute{color:#e6e1cf;}pre.rust .attribute .ident,pre.rust .attribute .op{color:#e6e1cf;}.example-wrap>pre.line-number{color:#5c67736e;border:none;}a.test-arrow{font-size:100%;color:#788797;border-radius:4px;background-color:rgba(57,175,215,0.09);}a.test-arrow:hover{background-color:rgba(57,175,215,0.368);color:#c5c5c5;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:rgba(255,236,164,0.06);border-right:3px solid rgba(255,180,76,0.85);}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.4);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#39AFD7;}.tooltip .tooltiptext{background-color:#314559;color:#c5c5c5;border:1px solid #5c6773;}.tooltip .tooltiptext::after{border-color:transparent #314559 transparent transparent;}.notable-traits-tooltiptext{background-color:#314559;border-color:#5c6773;}#titles>div.selected{background-color:#141920 !important;border-bottom:1px solid #ffb44c !important;border-top:none;}#titles>div:not(.selected){background-color:transparent !important;border:none;}#titles>div:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#titles>div>div.count{color:#888;}.content .highlighted.mod,.content .highlighted.externcrate{}.search-input:focus{}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{}.content .highlighted.trait{}.content span.struct,.content a.struct,.block a.current.struct{}#titles>div:hover,#titles>div.selected{}.content .highlighted.traitalias{}.content span.type,.content a.type,.block a.current.type{}.content span.union,.content a.union,.block a.current.union{}.content .highlighted.foreigntype{}pre.rust .lifetime{}.content .highlighted.primitive{}.content .highlighted.constant,.content .highlighted.static{}.stab.unstable{}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){}.content span.enum,.content a.enum,.block a.current.enum{}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{}.content span.keyword,.content a.keyword,.block a.current.keyword{}pre.rust .comment{}.content .highlighted.enum{}.content .highlighted.struct{}.content .highlighted.keyword{}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{}pre.rust .kw{}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{}pre.rust .doccomment{}.stab.deprecated{}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{}.stab.portability{}.content .highlighted.union{}.content span.primitive,.content a.primitive,.block a.current.primitive{}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{}.content .highlighted.type{}pre.rust .kw-2,pre.rust .prelude-ty{}.content span.trait,.content a.trait,.block a.current.trait{}@media (max-width:700px){.sidebar-menu{background-color:#14191f;border-bottom-color:#5c6773;border-right-color:#5c6773;}.sidebar-elems{background-color:#14191f;border-right-color:#5c6773;}#sidebar-filler{background-color:#14191f;border-bottom-color:#5c6773;}}kbd{color:#c5c5c5;background-color:#314559;border-color:#5c6773;border-bottom-color:#5c6773;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#5c6773;background-color:#0f1419;color:#fff;}#theme-picker>img,#settings-menu>img{filter:invert(100);}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#e0e0e0;}#theme-choices{border-color:#5c6773;background-color:#0f1419;}#theme-choices>button:not(:first-child){border-top-color:#5c6773;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:rgba(110,110,110,0.33);}@media (max-width:700px){#theme-picker{background:#0f1419;}}#all-types{background-color:#14191f;}#all-types:hover{background-color:rgba(70,70,70,0.33);}.search-results td span.alias{color:#c5c5c5;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#14191f;}#sidebar-toggle:hover{background-color:rgba(70,70,70,0.33);}#source-sidebar{background-color:#14191f;}#source-sidebar>.title{color:#fff;border-bottom-color:#5c6773;}div.files>a:hover,div.name:hover{background-color:#14191f;color:#ffb44c;}div.files>.selected{background-color:#14191f;color:#ffb44c;}.setting-line>.title{border-bottom-color:#5c6773;}input:checked+.slider{background-color:#ffb454 !important;} \ No newline at end of file diff --git a/book/.nojekyll b/book/.nojekyll new file mode 100644 index 000000000..863121594 --- /dev/null +++ b/book/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. \ No newline at end of file diff --git a/book/FontAwesome/css/font-awesome.css b/book/FontAwesome/css/font-awesome.css new file mode 100644 index 000000000..540440ce8 --- /dev/null +++ b/book/FontAwesome/css/font-awesome.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/book/FontAwesome/fonts/FontAwesome.ttf b/book/FontAwesome/fonts/FontAwesome.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/book/FontAwesome/fonts/FontAwesome.ttf differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.eot b/book/FontAwesome/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.eot differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.svg b/book/FontAwesome/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/book/FontAwesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/FontAwesome/fonts/fontawesome-webfont.ttf b/book/FontAwesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.ttf differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.woff b/book/FontAwesome/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.woff differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.woff2 b/book/FontAwesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.woff2 differ diff --git a/book/array_and_matrix_manipulation.html b/book/array_and_matrix_manipulation.html new file mode 100644 index 000000000..4b12b9975 --- /dev/null +++ b/book/array_and_matrix_manipulation.html @@ -0,0 +1,467 @@ + + + + + + Array and Matrix Manipulation - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Array and Matrix Manipulation

+

ArrayFire provides several different methods for manipulating arrays and matrices. The functionality +includes:

+
    +
  • moddims() - change the dimensions of an array without changing the data
  • +
  • flat() - flatten an array to one dimension
  • +
  • flip() - flip an array along a dimension
  • +
  • join() - join up to 4 arrays
  • +
  • reorder() - changes the dimension order within the array
  • +
  • shift() - shifts data along a dimension
  • +
  • tile() - repeats an array along a dimension
  • +
  • transpose() - performs a matrix transpose
  • +
+

Below we provide several examples of these functions and their use.

+

moddims()

+

The moddims function changes the dimensions of an array without changing its data or order. +Note that this function modifies only the metadata associated with the array. It does not modify +the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and +then back to a 8x1:

+
a [8 1 1 1]
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+
+let new_dims = Dim4::new(&[2, 4, 1, 1]);
+moddims(&a, new_dims)
+[2 4 1 1]
+    1.0000     1.0000     1.0000     1.0000
+    2.0000     2.0000     2.0000     2.0000
+
+let out = moddims(&a, a.elements(), 1, 1, 1);
+[8 1 1 1]
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+
+

flat()

+

The flat function flattens an array to one dimension:

+
a [3 3 1 1]
+    1.0000     4.0000     7.0000
+    2.0000     5.0000     8.0000
+    3.0000     6.0000     9.0000
+
+flat(&a)
+[9 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+    6.0000
+    7.0000
+    8.0000
+    9.0000
+
+

flip()

+

The flip function flips the contents of an array along a chosen dimension. In the example +below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. +across rows) axes:

+
a [5 2 1 1]
+    1.0000     6.0000
+    2.0000     7.0000
+    3.0000     8.0000
+    4.0000     9.0000
+    5.0000    10.0000
+
+flip(a, 0) [5 2 1 1]
+    5.0000    10.0000
+    4.0000     9.0000
+    3.0000     8.0000
+    2.0000     7.0000
+    1.0000     6.0000
+
+flip(a, 1) [5 2 1 1]
+    6.0000     1.0000
+    7.0000     2.0000
+    8.0000     3.0000
+    9.0000     4.0000
+   10.0000     5.0000
+
+

join()

+

The join, join_many functions can be used to join arrays along a specific dimension.

+

Here is an example of how to use join an array to itself:

+
a [5 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+
+join(0, a, a) [10 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+
+join(1, a, a) [5 2 1 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+    4.0000     4.0000
+    5.0000     5.0000
+
+

reorder()

+

The reorder function modifies the order of data within an array by exchanging data according to +the change in dimensionality. The linear ordering of data within the array is preserved.

+
a [2 2 3 1]
+    1.0000     3.0000
+    2.0000     4.0000
+
+    1.0000     3.0000
+    2.0000     4.0000
+
+    1.0000     3.0000
+    2.0000     4.0000
+
+
+reorder(&a, 1, 0, 2)
+[2 2 3 1]  //equivalent to a transpose
+    1.0000     2.0000
+    3.0000     4.0000
+
+    1.0000     2.0000
+    3.0000     4.0000
+
+    1.0000     2.0000
+    3.0000     4.0000
+
+
+reorder(&a, 2, 0, 1)
+[3 2 2 1]
+    1.0000     2.0000
+    1.0000     2.0000
+    1.0000     2.0000
+
+    3.0000     4.0000
+    3.0000     4.0000
+    3.0000     4.0000
+
+

shift()

+

The shift function shifts data in a circular buffer fashion along a chosen dimension. Consider +the following example:

+
a [3 5 1 1]
+    0.0000     0.0000     0.0000     0.0000     0.0000
+    3.0000     4.0000     5.0000     1.0000     2.0000
+    3.0000     4.0000     5.0000     1.0000     2.0000
+
+shift(&a, 0, 2 )
+[3 5 1 1]
+    0.0000     0.0000     0.0000     0.0000     0.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+
+shift(&a, -1, 2 )
+[3 5 1 1]
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    0.0000     0.0000     0.0000     0.0000     0.0000
+
+

tile()

+

The tile function repeats an array along the specified dimension. For example below we show how +to tile an array along the zeroth and first dimensions of an array:

+
a [3 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+
+// Repeat array a twice in the zeroth dimension
+tile(&a, 2)
+[6 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    1.0000
+    2.0000
+    3.0000
+
+// Repeat array a twice along both the zeroth and first dimensions
+tile(&a, 2, 2)
+[6 2 1 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+// Repeat array a twice along the first and three times along the second
+// dimension.
+let tile_dims = Dim4::new(&[1, 2, 3, 1]);
+tile(a, tile_dims) [3 2 3 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+

transpose()

+

The transpose function performs a standard matrix transpose. The input array must have the +dimensions of a 2D-matrix.

+
a [3 3 1 1]
+    1.0000     3.0000     3.0000
+    2.0000     1.0000     3.0000
+    2.0000     2.0000     1.0000
+
+transpose(&a, False) //Second parameter to be used for conjugate transpose
+[3 3 1 1]
+    1.0000     2.0000     2.0000
+    3.0000     1.0000     2.0000
+    3.0000     3.0000     1.0000
+
+

Combining functions to enumerate grid coordinates

+

By using a combination of the functions, one can quickly code complex manipulation patterns with +a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis +goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small +combination of the above functions.

+
let a      = iota::<u32>(Dim4::new(&[3, 1, 1, 1]),
+                         Dim4::new(&[1, 3, 1, 1]));
+let b      = transpose(&a, false);
+let coords = join(1, &flat(&a), &flat(&b));
+print(&coords);
+
+

The output for a [3 3 1 1] matrix will be the following.

+
[9 2 1 1]
+         0          0
+         1          0
+         2          0
+         0          1
+         1          1
+         2          1
+         0          2
+         1          2
+         2          2
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/ayu-highlight.css b/book/ayu-highlight.css new file mode 100644 index 000000000..128e01664 --- /dev/null +++ b/book/ayu-highlight.css @@ -0,0 +1,79 @@ +/* +Based off of the Ayu theme +Original by Dempfi (https://github.com/dempfi/ayu) +*/ + +.hljs { + display: block; + overflow-x: auto; + background: #191f26; + color: #e6e1cf; + padding: 0.5em; +} + +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #5c6773; + font-style: italic; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-attr, +.hljs-regexp, +.hljs-link, +.hljs-selector-id, +.hljs-selector-class { + color: #ff7733; +} + +.hljs-number, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #ffee99; +} + +.hljs-string, +.hljs-bullet { + color: #b8cc52; +} + +.hljs-title, +.hljs-built_in, +.hljs-section { + color: #ffb454; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-symbol { + color: #ff7733; +} + +.hljs-name { + color: #36a3d9; +} + +.hljs-tag { + color: #00568d; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #91b362; +} + +.hljs-deletion { + color: #d96c75; +} diff --git a/tutorials-book/src/theme/book.js b/book/book.js similarity index 100% rename from tutorials-book/src/theme/book.js rename to book/book.js diff --git a/book/clipboard.min.js b/book/clipboard.min.js new file mode 100644 index 000000000..02c549e35 --- /dev/null +++ b/book/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n + + + + + Configuring ArrayFire Runtime Environment - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Configuring Arrayfire Environment

+

Following are the list of environment and runtime configurations that will help enhance your +experience with ArrayFire.

+

AF_PATH

+

This is the path with ArrayFire gets installed, ie. the includes and libs are present in this +directory. You can use this variable to add include paths and libraries to your projects.

+

AF_PRINT_ERRORS

+

When AF\_PRINT\_ERRORS is set to 1, the exceptions thrown are more verbose and detailed. This +helps in locating the exact failure.

+
AF_PRINT_ERRORS=1 ./myprogram
+
+

AF_CUDA_DEFAULT_DEVICE

+

Use this variable to set the default CUDA device. Valid values for this variable are the device +identifiers shown when info is run.

+
AF_CUDA_DEFAULT_DEVICE=1 ./myprogram
+
+

Note: set_device call in the source code will take precedence over this variable.

+

AF_OPENCL_DEFAULT_DEVICE

+

Use this variable to set the default OpenCL device. Valid values for this variable are the device +identifiers shown when info is run.

+
AF_OPENCL_DEFAULT_DEVICE=1 ./myprogram
+
+

Note: set_device call in the source code will take precedence over this variable.

+

AF_OPENCL_DEFAULT_DEVICE_TYPE

+

Use this variable to set the default OpenCL device type. Valid values for this variable are: CPU, +GPU, ACC (Accelerators). When set, the first device of the specified type is chosen as default device.

+
AF_OPENCL_DEFAULT_DEVICE_TYPE=CPU ./myprogram
+
+

Note: AF_OPENCL_DEFAULT_DEVICE and set_device takes precedence over this variable.

+

AF_OPENCL_DEVICE_TYPE

+

Use this variable to only choose OpenCL devices of specified type. Valid values for this variable are:

+
    +
  • ALL: All OpenCL devices. (Default behavior).
  • +
  • CPU: CPU devices only.
  • +
  • GPU: GPU devices only.
  • +
  • ACC: Accelerator devices only.
  • +
+

When set, the remaining OpenCL device types are ignored by the OpenCL backend.

+
AF_OPENCL_DEVICE_TYPE=CPU ./myprogram
+
+

AF_OPENCL_CPU_OFFLOAD

+

When ArrayFire runs on devices with unified memory with the host (ie. CL_DEVICE_HOST_UNIFIED_MENORY +is true for the device) then certain functions are offloaded to run on the CPU using mapped buffers.

+

ArrayFire takes advantage of fast libraries such as MKL while spending no time copying memory from +device to host. The device memory is mapped to a host pointer which can be used in the offloaded +functions.

+

This functionality can be disabled by using the environment variable AF_OPENCL_CPU_OFFLOAD=0.

+

The default bevaior of this has changed in version 3.4. Prior to v3.4, CPU Offload functionality was +used only when the user set AF_OPENCL_CPU_OFFLOAD=1 and disabled otherwise. From v3.4 onwards, CPU +Offload is enabled by default and is disabled only when AF_OPENCL_CPU_OFFLOAD=0 is set.

+

AF_OPENCL_SHOW_BUILD_INFO

+

This variable is useful when debuggin OpenCL kernel compilation failures. When this variable is set +to 1, and an error occurs during a OpenCL kernel compilation, then the log and kernel are printed to screen.

+

AF_DISABLE_GRAPHICS

+

Setting this variable to 1 will disable window creation when graphics functions are being called. +Disabling window creation will disable all other graphics calls at runtime. This is a useful +when running code on servers and systems without displays. When graphics calls are run on such +machines, they will print warning about window creation failing. To suppress those calls, set this +variable.

+

AF_SYNCHRONOUS_CALLS

+

When this environment variable is set to 1, ArrayFire will execute all functions synchronously.

+

AF_SHOW_LOAD_PATH

+

When using the Unified backend, if this variable is set to 1, it will show the path where the ArrayFire +backend libraries are loaded from.

+

If the libraries are loaded from system paths, such as PATH or LD_LIBRARY_PATH etc, then it will +print "system path". If the libraries are loaded from other paths, then those paths are shown in full.

+

AF_MEM_DEBUG

+

When AF_MEM_DEBUG is set to 1 (or anything not equal to 0), the caching mechanism in the memory manager +is disabled. The device buffers are allocated using native functions as needed and freed when going out +of scope. When the environment variable is not set, it is treated to be non zero.

+
AF_MEM_DEBUG=1 ./myprogram
+
+

AF_MAX_BUFFERS

+

When AF_MAX_BUFFERS is set, this environment variable specifies the maximum number of buffers +allocated before garbage collection kicks in. Please note that the total number of buffers that +can exist simultaneously can be higher than this number. This variable tells the garbage collector +that it should free any available buffers immediately if the treshold is reached. When not set, +the default value is 1000.

+

AF_OPENCL_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum height of the OpenCL JIT tree after +which evaluation is forced. The default value, as of v3.4, is 50 on OSX, 100 everywhere else. +This value was 20 for older versions.

+

AF_CUDA_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum height of the CUDA JIT tree after +which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.

+

AF_CPU_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum length of the CPU JIT tree after +which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tutorials-book/src/theme/css/chrome.css b/book/css/chrome.css similarity index 100% rename from tutorials-book/src/theme/css/chrome.css rename to book/css/chrome.css diff --git a/tutorials-book/src/theme/css/general.css b/book/css/general.css similarity index 100% rename from tutorials-book/src/theme/css/general.css rename to book/css/general.css diff --git a/tutorials-book/src/theme/css/print.css b/book/css/print.css similarity index 100% rename from tutorials-book/src/theme/css/print.css rename to book/css/print.css diff --git a/tutorials-book/src/theme/css/variables.css b/book/css/variables.css similarity index 100% rename from tutorials-book/src/theme/css/variables.css rename to book/css/variables.css diff --git a/book/cuda-interop.html b/book/cuda-interop.html new file mode 100644 index 000000000..6442717f0 --- /dev/null +++ b/book/cuda-interop.html @@ -0,0 +1,439 @@ + + + + + + Interoperability with CUDA - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Interoperability with CUDA

+

Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom +kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to +increase your productivity, or you may need to supplement ArrayFire's functionality with your own +custom implementation of specific algorithms.

+

ArrayFire manages its own memory, runs within its own CUDA stream, and creates custom IDs for +devices. As such, most of the interoperability functions focus on reducing potential synchronization +conflicts between ArrayFire and CUDA.

+

Basics

+

It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides +several functions to ease this process including:

+ + + + + + + + + + +
FunctionPurpose
Array::new_from_device_ptrConstruct an ArrayFire Array from device memory
Array::device_ptrObtain a pointer to the device memory (implies lock())
Array::lockRemoves ArrayFire's control of a device memory pointer
Array::unlockRestores ArrayFire's control over a device memory pointer
get_deviceGets the current ArrayFire device ID
set_deviceSwitches ArrayFire to the specified device
get_device_native_idFetches CUDA deviceID for a given ArrayFire device ID
set_device_native_idSwitches active device to the specified CUDA device ID
get_streamGet the current CUDA stream used by ArrayFire
+

Using custom CUDA kernels in existing ArrayFire application

+

By default, ArrayFire manages its own memory and operates in its own CUDA stream. Thus there is a +slight amount of bookkeeping that needs to be done in order to integrate your custom CUDA kernel.

+

Ideally, we recommend using ArrayFire's CUDA stream to launch your custom kernels. However, this +is currently not possible due to limitation on RustaCUDA not being to able to wrap an +existing cudaStream_t/CUstream_t objects. The current work around is to create a stream of your +own and launch the kernel on it.

+

Notice that since ArrayFire and your kernels are not sharing the same CUDA stream, there is a need +to perform explicit synchronization before launching kernel on your stream that depends on the +computation carried out by ArrayFire earlier. This extra step is unnecessary once the above stated +limiation of RustaCUDA's stream is eliminated.

+

This process is best illustrated with a fully worked example:

+
use arrayfire as af;
+use rustacuda::prelude::*;
+use rustacuda::*;
+
+use std::ffi::CString;
+
+fn main() {
+    // MAKE SURE to do all rustacuda initilization before arrayfire API's
+    // first call. It seems like some CUDA context state is getting messed up
+    // if we mix CUDA context init(device, context, module, stream) with ArrayFire API
+    match rustacuda::init(CudaFlags::empty()) {
+        Ok(()) => {}
+        Err(e) => panic!("rustacuda init failure: {:?}", e),
+    }
+    let device = match Device::get_device(0) {
+        Ok(d) => d,
+        Err(e) => panic!("Failed to get device: {:?}", e),
+    };
+    let _context =
+        match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) {
+            Ok(c) => c,
+            Err(e) => panic!("Failed to create context: {:?}", e),
+        };
+    let ptx = CString::new(include_str!("./resources/add.ptx")).unwrap();
+    let module = match Module::load_from_string(&ptx) {
+        Ok(m) => m,
+        Err(e) => panic!("Failed to load module from string: {:?}", e),
+    };
+    let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) {
+        Ok(s) => s,
+        Err(e) => panic!("Failed to create stream: {:?}", e),
+    };
+
+    af::set_device(0);
+    af::info();
+
+    let num: i32 = 10;
+    let x = af::constant(1f32, af::dim4!(10));
+    let y = af::constant(2f32, af::dim4!(10));
+    let out = af::constant(0f32, af::dim4!(10));
+
+    af::af_print!("x", x);
+    af::af_print!("y", y);
+    af::af_print!("out(init)", out);
+
+    //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda
+    // let af_id = get_device();
+    // let cuda_id = get_device_native_id(af_id);
+    // let af_cuda_stream = get_stream(cuda_id);
+
+    //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda
+    // let stream = Stream {inner: mem::transmute(af_cuda_stream)};
+
+    // Run a custom CUDA kernel in the ArrayFire CUDA stream
+    unsafe {
+        // Obtain device pointers from ArrayFire using Array::device() method
+        let d_x: *mut f32 = x.device_ptr() as *mut f32;
+        let d_y: *mut f32 = y.device_ptr() as *mut f32;
+        let d_o: *mut f32 = out.device_ptr() as *mut f32;
+
+        match launch!(module.sum<<<1, 1, 0, stream>>>(
+        memory::DevicePointer::wrap(d_x),
+        memory::DevicePointer::wrap(d_y),
+        memory::DevicePointer::wrap(d_o),
+        num
+        )) {
+            Ok(()) => {}
+            Err(e) => panic!("Kernel Launch failure: {:?}", e),
+        }
+
+        // wait for the kernel to finish as it is async call
+        match stream.synchronize() {
+            Ok(()) => {}
+            Err(e) => panic!("Stream sync failure: {:?}", e),
+        };
+
+        // Return control of Array memory to ArrayFire using unlock
+        x.unlock();
+        y.unlock();
+        out.unlock();
+    }
+    af::af_print!("sum after kernel launch", out);
+}
+
+
+

Adding ArrayFire to existing CUDA Application

+

Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due +to several optimizations we implement. The most important are as follows:

+
    +
  • ArrayFire assumes control of all memory provided to it.
  • +
  • ArrayFire does not (in general) support in-place memory transactions.
  • +
+

We will discuss the implications of these items below. To add ArrayFire to existing code you need to:

+
    +
  1. Finish any pending CUDA operations (e.g. cudaDeviceSynchronize() or similar stream functions)
  2. +
  3. Create ArrayFire arrays from existing CUDA pointers
  4. +
  5. Perform operations on ArrayFire arrays
  6. +
  7. Instruct ArrayFire to finish operations using eval and sync
  8. +
  9. Obtain pointers to important memory
  10. +
  11. Continue your CUDA application.
  12. +
  13. Free non-managed memory
  14. +
+

To create the Array fom device pointer, you should use one of the following approaches:

+

Using DeviceBuffer from RustaCUDA, or a Wrapper Object for CUDA device memory

+

+# #![allow(unused_variables)]
+#fn main() {
+let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap();
+
+let array_dptr = Array::new_from_device_ptr(
+    buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10));
+
+array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership
+#}
+

Using raw pointer returned from cuda_malloc interface exposed by RustaCUDA

+

+# #![allow(unused_variables)]
+#fn main() {
+let mut dptr: *mut f32 = std::ptr::null_mut();
+unsafe {
+    dptr = memory::cuda_malloc::<f32>(10*10).unwrap().as_raw_mut();
+}
+
+let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));
+// After ArrayFire takes over ownership of the pointer, you can use other
+// arrayfire functions as usual.
+#}
+

ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. +Thus ArrayFire could free or reuse the memory at any later time. If this behavior is not desired, +you may call Array::unlock and manage the memory yourself. However, if you do so, please be +cautious not to free memory when ArrayFire might be using it!

+

The seven steps above are best illustrated using a fully-worked example:

+
use arrayfire::{af_print, dim4, info, set_device, Array};
+use rustacuda::prelude::*;
+
+fn main() {
+    // MAKE SURE to do all rustacuda initilization before arrayfire API's
+    // first call. It seems like some CUDA context state is getting messed up
+    // if we mix CUDA context init(device, context, module, stream) with ArrayFire API
+    match rustacuda::init(CudaFlags::empty()) {
+        Ok(()) => {}
+        Err(e) => panic!("rustacuda init failure: {:?}", e),
+    }
+    let device = match Device::get_device(0) {
+        Ok(d) => d,
+        Err(e) => panic!("Failed to get device: {:?}", e),
+    };
+    let _context =
+        match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) {
+            Ok(c) => c,
+            Err(e) => panic!("Failed to create context: {:?}", e),
+        };
+    let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) {
+        Ok(s) => s,
+        Err(e) => panic!("Failed to create stream: {:?}", e),
+    };
+
+    let mut in_x = DeviceBuffer::from_slice(&[1.0f32; 10]).unwrap();
+    let mut in_y = DeviceBuffer::from_slice(&[2.0f32; 10]).unwrap();
+
+    // wait for any prior kernels to finish before passing
+    // the device pointers to ArrayFire
+    match stream.synchronize() {
+        Ok(()) => {}
+        Err(e) => panic!("Stream sync failure: {:?}", e),
+    };
+
+    set_device(0);
+    info();
+
+    let x = Array::new_from_device_ptr(in_x.as_device_ptr().as_raw_mut(), dim4!(10));
+    let y = Array::new_from_device_ptr(in_y.as_device_ptr().as_raw_mut(), dim4!(10));
+
+    // Lock so that ArrayFire doesn't free pointers from RustaCUDA
+    // But we have to make sure these pointers stay in valid scope
+    // as long as the associated ArrayFire Array objects are valid
+    x.lock();
+    y.lock();
+
+    af_print!("x", x);
+    af_print!("y", y);
+
+    let o = x + y;
+    af_print!("out", o);
+
+    let _o_dptr = unsafe { o.device_ptr() }; // Calls an implicit lock
+
+    // User has to call unlock if they want to relenquish control to ArrayFire
+
+    // Once the non-arrayfire operations are done, call unlock.
+    o.unlock(); // After this, there is no guarantee that value of o_dptr is valid
+}
+
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/elasticlunr.min.js b/book/elasticlunr.min.js new file mode 100644 index 000000000..94b20dd2e --- /dev/null +++ b/book/elasticlunr.min.js @@ -0,0 +1,10 @@ +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5 + * + * Copyright (C) 2017 Oliver Nightingale + * Copyright (C) 2017 Wei Song + * MIT Licensed + * @license + */ +!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o + + + + + Getting Started - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

ArrayFire is a high performance software library for parallel computing with an easy-to-use API. +ArrayFire abstracts away much of the details of programming parallel architectures by providing +a high-level container object, the Array, that represents data stored on a CPU, GPU, FPGA, +or other type of accelerator. This abstraction permits developers to write massively parallel +applications in a high-level language where they need not be concerned about low-level optimizations +that are frequently required to achieve high throughput on most parallel architectures.

+

Supported data types

+

ArrayFire provides one generic container object, the Array on which functions and mathematical +operations are performed. The Array can represent one of many different basic data types:

+
    +
  • F32 real single-precision (float)
  • +
  • C32 complex single-precision (cfloat)
  • +
  • F64 real double-precision (double)
  • +
  • C64 complex double-precision (cdouble)
  • +
  • B8 8-bit boolean values (bool)
  • +
  • S32 32-bit signed integer (int)
  • +
  • U32 32-bit unsigned integer (unsigned)
  • +
  • U8 8-bit unsigned values (unsigned char)
  • +
  • S64 64-bit signed integer (intl)
  • +
  • U64 64-bit unsigned integer (uintl)
  • +
  • S16 16-bit signed integer (short)
  • +
  • U16 16-bit unsigned integer (unsigned short)
  • +
  • F16 16-bit floating point number (half::f16)
  • +
+

Most of these data types are supported on all modern GPUs; however, some older devices may lack +support for double precision arrays. In this case, a runtime error will be generated when the array +is constructed.

+

If not specified, Arrays are created as single precision floating point numbers (F32).

+

Creating and populating an Array

+

ArrayFire Array's represent memory stored on the device. As such, creation and population of +an array will consume memory on the device which cannot freed until the array object goes out of +scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which +will re-use device memory whenever possible.

+

Arrays can be created using one of the array constructors. Below we show how to create 1D, 2D, +and 3D arrays with uninitialized values:

+
let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32);
+
+

However, uninitialized memory is likely not useful in your application. ArrayFire provides several +convenient functions for creating arrays that contain pre-populated values including constants, +uniform random numbers, uniform normally distributed numbers, and the identity matrix:

+
// Create an array filled with constant value of 2.0 of type floating point
+// The type of Array is infered from the type of the constant argument
+let cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1]));
+print(&cnst);
+
+
println!("Create a 5-by-3 matrix of random floats on the GPU");
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+
+

As stated above, the default data type for arrays is F32(32-bit floating point number) unless +specified otherwise.

+

ArrayFire Arrays may also be populated from data found on the host. For example:

+
let values: [u32; 3] = [1u32, 2, 3];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

Properties of an Array

+

ArrayFire provides several functions to determine various aspects of arrays. This includes +functions to print the contents, query dimensions, and determine various other aspects of arrays.

+

The print function can be used to print arrays that have already been generated or any +expression involving arrays:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

The dimensions of an array may be determined using either a Dim4 object or by accessing the +dimensions directly using the Dim4::get and Dim4::numdims functions:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let dims: Dim4 = Dim4::new(&[3, 1, 1, 1]);
+let indices = Array::new(&values, dims);
+println!("Dims {:?} with dimensions {}", dims.get(), dims.ndims());
+
+

In addition to dimensions, arrays also carry several properties including methods to determine the +underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, +a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you +consult the full documentation on the Array.

+

Writing math expressions using ArrayFire

+

ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions +using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, +ArrayFire functions like a vector library. That means that an element-wise operation, like +c[i] = a[i] + b[i] in C, would be written more concisely without indexing, like c = a + b. When +there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. +his "kernel fusion" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations.

+

Our JIT functionality extends across C API boundary and only ends when a non-JIT function is +encountered or a synchronization operation is explicitly called by the code.

+

ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators +(e.g. +,-,*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples:

+
let num_rows: u64 = 5;
+let num_cols: u64 = 3;
+let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
+let a = randu::<f32>(dims);
+let b = randu::<f32>(dims);
+print(&a);
+print(&b);
+let c = a + b;
+print(&c);
+
+//Example of *Assign traits
+let mut d = randu::<f32>(dims);
+let e     = constant(1f32, dims);
+d += e;
+print(&d);
+
+

Indexing

+

Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To +index Arrays you may use one or a combination of the following functions:

+ +

Please see the indexing page for several examples of how to use these functions.

+

Access to Array memory on the host

+

Memory in af::Arrays may be accessed using the Array::host() method. The host function +copies the data from the device and makes it available in a standard slice or similar container on +the host. As such, it is up to the developer to manage any memory returned by host.

+ +

Bitwise operators

+

In addition to supporting standard mathematical functions, Arrays that contain integer data types +also support bitwise operators including and, or, and shift etc. Operator traits for Array as well +as separate functions are also defined to support various use cases.

+
let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<bool>(dims);
+let b = randu::<bool>(dims);
+
+print(&a);
+print(&b);
+
+let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid
+let d = bitand(&a, &b, false);
+
+print(&c);
+print(&d);
+
+

Where to go for help?

+ + +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tutorials-book/src/theme/highlight.css b/book/highlight.css similarity index 100% rename from tutorials-book/src/theme/highlight.css rename to book/highlight.css diff --git a/tutorials-book/src/theme/highlight.js b/book/highlight.js similarity index 100% rename from tutorials-book/src/theme/highlight.js rename to book/highlight.js diff --git a/book/index.html b/book/index.html new file mode 100644 index 000000000..811a487db --- /dev/null +++ b/book/index.html @@ -0,0 +1,343 @@ + + + + + + Getting Started - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

ArrayFire is a high performance software library for parallel computing with an easy-to-use API. +ArrayFire abstracts away much of the details of programming parallel architectures by providing +a high-level container object, the Array, that represents data stored on a CPU, GPU, FPGA, +or other type of accelerator. This abstraction permits developers to write massively parallel +applications in a high-level language where they need not be concerned about low-level optimizations +that are frequently required to achieve high throughput on most parallel architectures.

+

Supported data types

+

ArrayFire provides one generic container object, the Array on which functions and mathematical +operations are performed. The Array can represent one of many different basic data types:

+
    +
  • F32 real single-precision (float)
  • +
  • C32 complex single-precision (cfloat)
  • +
  • F64 real double-precision (double)
  • +
  • C64 complex double-precision (cdouble)
  • +
  • B8 8-bit boolean values (bool)
  • +
  • S32 32-bit signed integer (int)
  • +
  • U32 32-bit unsigned integer (unsigned)
  • +
  • U8 8-bit unsigned values (unsigned char)
  • +
  • S64 64-bit signed integer (intl)
  • +
  • U64 64-bit unsigned integer (uintl)
  • +
  • S16 16-bit signed integer (short)
  • +
  • U16 16-bit unsigned integer (unsigned short)
  • +
  • F16 16-bit floating point number (half::f16)
  • +
+

Most of these data types are supported on all modern GPUs; however, some older devices may lack +support for double precision arrays. In this case, a runtime error will be generated when the array +is constructed.

+

If not specified, Arrays are created as single precision floating point numbers (F32).

+

Creating and populating an Array

+

ArrayFire Array's represent memory stored on the device. As such, creation and population of +an array will consume memory on the device which cannot freed until the array object goes out of +scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which +will re-use device memory whenever possible.

+

Arrays can be created using one of the array constructors. Below we show how to create 1D, 2D, +and 3D arrays with uninitialized values:

+
let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32);
+
+

However, uninitialized memory is likely not useful in your application. ArrayFire provides several +convenient functions for creating arrays that contain pre-populated values including constants, +uniform random numbers, uniform normally distributed numbers, and the identity matrix:

+
// Create an array filled with constant value of 2.0 of type floating point
+// The type of Array is infered from the type of the constant argument
+let cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1]));
+print(&cnst);
+
+
println!("Create a 5-by-3 matrix of random floats on the GPU");
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+
+

As stated above, the default data type for arrays is F32(32-bit floating point number) unless +specified otherwise.

+

ArrayFire Arrays may also be populated from data found on the host. For example:

+
let values: [u32; 3] = [1u32, 2, 3];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

Properties of an Array

+

ArrayFire provides several functions to determine various aspects of arrays. This includes +functions to print the contents, query dimensions, and determine various other aspects of arrays.

+

The print function can be used to print arrays that have already been generated or any +expression involving arrays:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

The dimensions of an array may be determined using either a Dim4 object or by accessing the +dimensions directly using the Dim4::get and Dim4::numdims functions:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let dims: Dim4 = Dim4::new(&[3, 1, 1, 1]);
+let indices = Array::new(&values, dims);
+println!("Dims {:?} with dimensions {}", dims.get(), dims.ndims());
+
+

In addition to dimensions, arrays also carry several properties including methods to determine the +underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, +a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you +consult the full documentation on the Array.

+

Writing math expressions using ArrayFire

+

ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions +using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, +ArrayFire functions like a vector library. That means that an element-wise operation, like +c[i] = a[i] + b[i] in C, would be written more concisely without indexing, like c = a + b. When +there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. +his "kernel fusion" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations.

+

Our JIT functionality extends across C API boundary and only ends when a non-JIT function is +encountered or a synchronization operation is explicitly called by the code.

+

ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators +(e.g. +,-,*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples:

+
let num_rows: u64 = 5;
+let num_cols: u64 = 3;
+let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
+let a = randu::<f32>(dims);
+let b = randu::<f32>(dims);
+print(&a);
+print(&b);
+let c = a + b;
+print(&c);
+
+//Example of *Assign traits
+let mut d = randu::<f32>(dims);
+let e     = constant(1f32, dims);
+d += e;
+print(&d);
+
+

Indexing

+

Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To +index Arrays you may use one or a combination of the following functions:

+ +

Please see the indexing page for several examples of how to use these functions.

+

Access to Array memory on the host

+

Memory in af::Arrays may be accessed using the Array::host() method. The host function +copies the data from the device and makes it available in a standard slice or similar container on +the host. As such, it is up to the developer to manage any memory returned by host.

+ +

Bitwise operators

+

In addition to supporting standard mathematical functions, Arrays that contain integer data types +also support bitwise operators including and, or, and shift etc. Operator traits for Array as well +as separate functions are also defined to support various use cases.

+
let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<bool>(dims);
+let b = randu::<bool>(dims);
+
+print(&a);
+print(&b);
+
+let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid
+let d = bitand(&a, &b, false);
+
+print(&c);
+print(&d);
+
+

Where to go for help?

+ + +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/indexing.html b/book/indexing.html new file mode 100644 index 000000000..0bec84966 --- /dev/null +++ b/book/indexing.html @@ -0,0 +1,439 @@ + + + + + + Indexing - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Indexing

+

Indexing in ArrayFire is a powerful but easy to abuse feature. This feature allows you to reference +or copy subsections of a larger array and perform operations on only a subset of elements.

+

This chapter is split into the following sections:

+ +

Indexer structure is the key element used in Rust wrapper of ArrayFire for creating references +to existing Arrays. The above sections illustrate how it can be used in conjunction with Seq +and/or Array. Apart from that, each section also showcases a macro based equivalent +code(if one exists) that is more terse in syntax but offers the same functionality.

+

Using Seq objects

+

Create a view of an existing Array

+

We will Sequences and the function index in this approach.

+
        let dims = Dim4::new(&[5, 5, 1, 1]);
+        let a = randu::<f32>(dims);
+        //af_print!("a", a);
+        //a
+        //[5 5 1 1]
+        //    0.3990     0.5160     0.8831     0.9107     0.6688
+        //    0.6720     0.3932     0.0621     0.9159     0.8434
+        //    0.5339     0.2706     0.7089     0.0231     0.1328
+        //    0.1386     0.9455     0.9434     0.2330     0.2657
+        //    0.7353     0.1587     0.1227     0.2220     0.2299
+
+        // Index array using sequences
+        let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
+        let _sub = index(&a, seqs);
+        //af_print!("a(seq(1,3,1), span)", sub);
+        // [3 5 1 1]
+        //     0.6720     0.3932     0.0621     0.9159     0.8434
+        //     0.5339     0.2706     0.7089     0.0231     0.1328
+        //     0.1386     0.9455     0.9434     0.2330     0.2657
+
+

However, the same above code can be condensed into a much terse syntax with the help of view +macro. Take a look at the following two approaches using view macro.

+
        let dims = dim4!(5, 5, 1, 1);
+        let a = randu::<f32>(dims);
+        let first3 = seq!(1:3:1);
+        let allindim2 = seq!();
+        let _sub = view!(a[first3, allindim2]);
+
+
OR
+
        let a = randu::<f32>(dim4!(5, 5));
+        let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis
+
+
+

Modify a sub region of an existing Array

+

Let us take a look at an example where a portion of an existing Array will be set to with another +Array. We will an constant value Array and the function assign_seq in the below example.

+
        let mut a = constant(2.0 as f32, dim4!(5, 3));
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+
+        let b = constant(1.0 as f32, dim4!(3, 3));
+        let seqs = [seq!(1:3:1), seq!()];
+        assign_seq(&mut a, &seqs, &b);
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 2.0 2.0 2.0
+
+

A much terser way of doing the same using macro is shown below

+
        let mut a = randu::<f32>(dim4!(5, 5));
+        let b = randu::<f32>(dim4!(2, 2));
+        eval!(a[1:2:1, 1:2:1] = b);
+
+
+

NOTE Normally you want to avoid accessing individual elements of the array like this for performance reasons.

+
+

Using Array and Seq combination

+

Create a view of an existing Array

+

To use a combination of Array and Seq objects to index an existing Array, we will need a more +generalized function index_gen.

+
        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = Seq::new(0.0, 2.0, 1.0);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        // [5 3 1 1]
+        //     0.0000     0.2190     0.3835
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+        //     0.5328     0.9347     0.0535
+
+        let mut idxrs = Indexer::default();
+        idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+        idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+        let _sub2 = index_gen(&a, idxrs);
+        //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+        // [3 3 1 1]
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+
+

Similar to how view macro helped with abreviating the syntax when indexing with just +sequences, it can also help when using a combination of Seq and Array.

+
        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = seq!(0:2:1);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        let _sub2 = view!(a[indices, seq4gen]);
+
+

Modify a sub region of an existing Array

+

Set a portion of an existing Array with another Array using a combination of Seq and Array. +We will use assign_gen function to do it.

+
       let values: [f32; 3] = [1.0, 2.0, 3.0];
+       let indices = Array::new(&values, dim4!(3, 1, 1, 1));
+       let seq4gen = seq!(0:2:1);
+       let mut a = randu::<f32>(dim4!(5, 3, 1, 1));
+       // [5 3 1 1]
+       //     0.0000     0.2190     0.3835
+       //     0.1315     0.0470     0.5194
+       //     0.7556     0.6789     0.8310
+       //     0.4587     0.6793     0.0346
+       //     0.5328     0.9347     0.0535
+
+       let b = constant(2.0 as f32, dim4!(3, 3, 1, 1));
+
+       let mut idxrs = Indexer::default();
+       idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+       idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+       let _sub2 = assign_gen(&mut a, &idxrs, &b);
+       //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+       // [5 3 1 1]
+       //     0.0000     0.2190     0.3835
+       //     2.0000     2.0000     2.0000
+       //     2.0000     2.0000     2.0000
+       //     2.0000     2.0000     2.0000
+       //     0.5328     0.9347     0.0535
+
+
OR
+
       let values: [f32; 3] = [1.0, 2.0, 3.0];
+       let indices = Array::new(&values, dim4!(3));
+       let seq4gen = seq!(0:2:1);
+       let mut a = randu::<f32>(dim4!(5, 3));
+
+       let b = constant(2.0 as f32, dim4!(3, 3));
+
+       eval!(a[indices, seq4gen] = b);
+
+

Extract or Set rows/columns of an Array

+

Extract a specific set of rows/coloumns from an existing Array.

+
        let a = randu::<f32>(dim4!(5, 5, 1, 1));
+        //print(&a);
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, 4);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, 4);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+
+

You can also use rows & cols to retrieve a subset of rows or coloumns respectively.

+

Similarly, set_row & set_rows can be used to change the values in a particular set of +rows using another Array. set_col & set_cols has same functionality, except that it is +for coloumns.

+

Negative Indices

+

Negative indices can also be used to refer elements from the end of a given axis. Negative value for +a row/column/slice will fetch corresponding row/column/slice in reverse order. Given below are some +examples that showcase getting row(s)/col(s) from an existing Array.

+
        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, -1);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, -1);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+
+
        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = rows(&a, -1, -2);
+        // [2 5 1 1]
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = cols(&a, -1, -3);
+        // [5 3 1 1]
+        //     0.1583     0.3636     0.6755
+        //     0.3712     0.4165     0.6105
+        //     0.3543     0.5814     0.5232
+        //     0.6450     0.8962     0.5567
+        //     0.9675     0.3712     0.7896
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/mark.min.js b/book/mark.min.js new file mode 100644 index 000000000..163623188 --- /dev/null +++ b/book/mark.min.js @@ -0,0 +1,7 @@ +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),o=function(){function e(n){t(this,e),this.opt=r({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},n)}return n(e,[{key:"create",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,"gm"+(this.opt.caseSensitive?"":"i"))}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynonyms(a)+"|"+this.processSynonyms(s)+")"+r))}return e}},{key:"processSynonyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return i.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapGroups",value:function(e,t,n,r){return r((e=this.wrapRangeInTextNode(e,t,t+n)).previousSibling),e}},{key:"separateGroups",value:function(e,t,n,r,i){for(var o=t.length,a=1;a-1&&r(t[a],e)&&(e=this.wrapGroups(e,s,t[a].length,i))}return e}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];){if(o.opt.separateGroups)t=o.separateGroups(t,i,a,n,r);else{if(!n(i[a],t))continue;var s=i.index;if(0!==a)for(var c=1;c + + + + + Multhi-Threading - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

ArrayFire in Threaded Applications

+

In this chapter, we will looking at how to use ArrayFire in multi-threaded programs. We shall +go over the details in the following order.

+ +

Move an Array to thread

+

In this section, we are going to create an Array on main thread and move it to a child thread, +modify it and then print it from the child thread.

+
        set_device(0);
+        info();
+        let mut a = constant(1, dim4!(3, 3));
+
+        let handle = thread::spawn(move || {
+            //set_device to appropriate device id is required in each thread
+            set_device(0);
+
+            println!("\nFrom thread {:?}", thread::current().id());
+
+            a += constant(2, dim4!(3, 3));
+            print(&a);
+        });
+
+        //Need to join other threads as main thread holds arrayfire context
+        handle.join().unwrap();
+
+

Read Array from Multiple threads

+

Now, let's expand the earlier example to do a bunch of arithmetic operations in parallel on +multiple threads using the same Array objects.

+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        // ArrayFire Array's are internally maintained via atomic reference counting
+        // Thus, they need no Arc wrapping while moving to another thread.
+        // Just call clone method on the object and share the resulting clone object
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+                thread::spawn(move || {
+                    set_device(0); //Both of objects are created on device 0 earlier
+                    match op {
+                        Op::Add => {
+                            let _c = x + y;
+                        }
+                        Op::Sub => {
+                            let _c = x - y;
+                        }
+                        Op::Div => {
+                            let _c = x / y;
+                        }
+                        Op::Mul => {
+                            let _c = x * y;
+                        }
+                    }
+                    sync(0);
+                    thread::sleep(std::time::Duration::new(1, 0));
+                })
+            })
+            .collect();
+        for child in threads {
+            let _ = child.join();
+        }
+
+

Given below is the definition of the enum Op we used in the example for illustration simplicity.

+
    #[derive(Debug, Copy, Clone)]
+    enum Op {
+        Add,
+        Sub,
+        Div,
+        Mul,
+    }
+
+

Write to Array from Multiple threads

+

Let us further expand the earlier example by accumulating the results of the arithmetic operations +into a single Array object.

+

The code will differ from earlier section in couple of locations:

+
    +
  • In the main thread, we wrap the accumulating Array in a read-write lock (std::sync::RwLock) +which is in turn wrapped in an atomically reference counted counter a.k.a std::sync::Arc.
  • +
  • In the children threads, we use the guarded objects returned by RwLock's write method to access +the accumulator Array.
  • +
+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        // Move ownership to RwLock and wrap in Arc since same object is to be modified
+        let c_lock = Arc::new(RwLock::new(c));
+
+        // a and b are internally reference counted by ArrayFire. Unless there
+        // is prior known need that they may be modified, you can simply clone
+        // the objects pass them to threads
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+
+                let wlock = c_lock.clone();
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+                    if let Ok(mut c_guard) = wlock.write() {
+                        match op {
+                            Op::Add => {
+                                *c_guard += x + y;
+                            }
+                            Op::Sub => {
+                                *c_guard += x - y;
+                            }
+                            Op::Div => {
+                                *c_guard += x / y;
+                            }
+                            Op::Mul => {
+                                *c_guard += x * y;
+                            }
+                        }
+                    }
+                })
+            })
+            .collect();
+
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //let read_guard = c_lock.read().unwrap();
+        //af_print!("C after threads joined", *read_guard);
+        //C after threads joined
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+
+

Write to single Array using Channel

+

In this section, we shall modify the example to use channel instead of data sharing.

+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+        let ops_len: usize = ops.len();
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let mut c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let (tx, rx) = mpsc::channel();
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                // a and b are internally reference counted by ArrayFire. Unless there
+                // is prior known need that they may be modified, you can simply clone
+                // the objects pass them to threads
+                let x = a.clone();
+                let y = b.clone();
+
+                let tx_clone = tx.clone();
+
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+
+                    let c = match op {
+                        Op::Add => x + y,
+                        Op::Sub => x - y,
+                        Op::Div => x / y,
+                        Op::Mul => x * y,
+                    };
+                    tx_clone.send(c).unwrap();
+                })
+            })
+            .collect();
+
+        for _i in 0..ops_len {
+            c += rx.recv().unwrap();
+        }
+
+        //Need to join other threads as main thread holds arrayfire context
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //af_print!("C after accumulating results", &c);
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/opencl-interop.html b/book/opencl-interop.html new file mode 100644 index 000000000..e43537d85 --- /dev/null +++ b/book/opencl-interop.html @@ -0,0 +1,448 @@ + + + + + + Interoperability with OpenCL - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Interoperability with OpenCL

+

Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom +kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to +increase your productivity, or you may need to supplement ArrayFire's functionality with your own +custom implementation of specific algorithms.

+

ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. As such, most +of the interoperability functions focus on reducing potential synchronization conflicts between +ArrayFire and OpenCL.

+

Basics

+

It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides +several functions to ease this process including:

+ + + + + + + + + + + + + +
FunctionPurpose
Array::new_from_device_ptrConstruct an ArrayFire Array from cl_mem
Array::device_ptrObtain a pointer to the device memory (implies lock)
Array::lockRemoves ArrayFire's control of a device memory pointer
Array::unlockRestores ArrayFire's control over a device memory pointer
get_platformGet ArrayFire's current cl_platform
get_deviceGets the current ArrayFire device ID
get_device_idGet ArrayFire's current cl_device_id
set_device_idSet ArrayFire's device from a cl_device_id
set_deviceSwitches ArrayFire to the specified device
get_contextGet ArrayFire's current cl_context
get_queueGet ArrayFire's current cl_command_queue
get_device_typeGet the current DeviceType
+

Note that the pointer returned by Array::device_ptr should be cast to cl_mem before using +it with OpenCL opaque types. The pointer is a cl_mem internally that is force casted to pointer +type by ArrayFire before returning the value to caller.

+

Additionally, the OpenCL backend permits the programmer to add and remove custom devices from the +ArrayFire device manager. These permit you to attach ArrayFire directly to the OpenCL queue used by +other portions of your application.

+ + + + +
FunctionPurpose
add_device_contextAdd a new device to ArrayFire's device manager
set_device_contextSet ArrayFire's device from cl_device_id & cl_context
delete_device_contextRemove a device from ArrayFire's device manager
+

Below we provide two worked examples on how ArrayFire can be integrated +into new and existing projects.

+

Adding custom OpenCL kernels to an existing ArrayFire application

+

By default, ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. +Thus there is some bookkeeping that needs to be done to integrate your custom OpenCL kernel.

+

If your kernels can share operate in the same queue as ArrayFire, you should:

+
    +
  1. Obtain the OpenCL context, device, and queue used by ArrayFire
  2. +
  3. Obtain cl_mem references to Array objects
  4. +
  5. Load, build, and use your kernels
  6. +
  7. Return control of Array memory to ArrayFire
  8. +
+

Note, ArrayFire uses an in-order queue, thus when ArrayFire and your kernels are operating in the +same queue, there is no need to perform any synchronization operations.

+

This process is best illustrated with a fully worked example:

+
//! A trivial example. Copied from ocl-core crate repository.
+use af_opencl_interop as afcl;
+use arrayfire as af;
+
+use ocl_core::{ArgVal, Event};
+
+use std::ffi::CString;
+
+fn main() {
+    af::info();
+    let dims = af::dim4!(8);
+    let af_buffer = af::constant(0f32, dims.clone());
+    af::af_print!("af_buffer", af_buffer);
+
+    let src = r#"
+        __kernel void add(__global float* buffer, float scalar) {
+            buffer[get_global_id(0)] += scalar;
+        }
+    "#;
+
+    let af_did = afcl::get_device_id();
+    let af_ctx = afcl::get_context(false);
+    let af_que = afcl::get_queue(false);
+
+    let _devid = unsafe { ocl_core::DeviceId::from_raw(af_did) };
+    let contx = unsafe { ocl_core::Context::from_raw_copied_ptr(af_ctx) };
+    let queue = unsafe { ocl_core::CommandQueue::from_raw_copied_ptr(af_que) };
+
+    // Define which platform and device(s) to use. Create a context,
+    // queue, and program then define some dims..
+    let src_cstring = CString::new(src).unwrap();
+    let program = ocl_core::create_program_with_source(&contx, &[src_cstring]).unwrap();
+    ocl_core::build_program(
+        &program,
+        None::<&[()]>,
+        &CString::new("").unwrap(),
+        None,
+        None,
+    )
+    .unwrap();
+
+    // Fetch cl_mem from ArrayFire Array
+    let ptr = unsafe { af_buffer.device_ptr() };
+    let buffer = unsafe { ocl_core::Mem::from_raw_copied_ptr(ptr) };
+
+    // Create a kernel with arguments matching those in the source above:
+    let kernel = ocl_core::create_kernel(&program, "add").unwrap();
+    ocl_core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap();
+    ocl_core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap();
+
+    let ocl_dims: [usize; 3] = [dims[0] as usize, dims[1] as usize, dims[2] as usize];
+    unsafe {
+        ocl_core::enqueue_kernel(
+            &queue,
+            &kernel,
+            1,
+            None,
+            &ocl_dims,
+            None,
+            None::<Event>,
+            None::<&mut Event>,
+        )
+        .unwrap();
+    }
+    ocl_core::finish(&queue).unwrap();
+    af_buffer.unlock(); //Give back control of cl_mem to ArrayFire memory manager
+
+    af::af_print!("af_buffer after running Custom Kernel on it", af_buffer);
+}
+
+
+

If your kernels needs to operate in their own OpenCL queue, the process is essentially identical, +except you need to instruct ArrayFire to complete its computations using the sync function +prior to launching your own kernel and ensure your kernels are complete using clFinish +(or similar) commands prior to returning control of the memory to ArrayFire:

+
    +
  1. Obtain the OpenCL context, device, and queue used by ArrayFire
  2. +
  3. Obtain cl_mem references to Array objects
  4. +
  5. Instruct ArrayFire to finish operations using sync
  6. +
  7. Load, build, and use your kernels
  8. +
  9. Instruct OpenCL to finish operations using clFinish() or similar commands.
  10. +
  11. Return control of Array memory to ArrayFire
  12. +
+

Adding ArrayFire to an existing OpenCL application

+

Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due +to several optimizations we implement. The most important are as follows:

+
    +
  • ArrayFire assumes control of all memory provided to it.
  • +
  • ArrayFire does not (in general) support in-place memory transactions.
  • +
+

We will discuss the implications of these items below. To add ArrayFire to existing code you need to:

+
    +
  1. Instruct OpenCL to complete its operations using clFinish (or similar)
  2. +
  3. Instruct ArrayFire to use the user-created OpenCL Context
  4. +
  5. Create ArrayFire arrays from OpenCL memory objects
  6. +
  7. Perform ArrayFire operations on the Arrays
  8. +
  9. Instruct ArrayFire to finish operations using sync
  10. +
  11. Obtain cl_mem references for important memory
  12. +
  13. Continue your OpenCL application
  14. +
+ +
+

ArrayFire's memory manager automatically assumes responsibility for any memory provided to +it. If you are creating an array from another RAII style object, you should retain it to ensure +your memory is not deallocated if your RAII object were to go out of scope.

+
+
+

If you do not wish for ArrayFire to manage your memory, you may call the Array::unlock +function and manage the memory yourself; however, if you do so, please be cautious not to call +clReleaseMemObj on a cl_mem when ArrayFire might be using it!

+
+

Given below is a fully working example:

+
//! A trivial example. Copied from ocl-core crate repository.
+use af_opencl_interop as afcl;
+use arrayfire as af;
+
+use ocl_core::{ContextProperties, Event};
+
+fn main() {
+    // Choose platform & device(s) to use. Create a context, queue,
+    let platform_id = ocl_core::default_platform().unwrap();
+    let device_ids = ocl_core::get_device_ids(&platform_id, None, None).unwrap();
+    let device_id = device_ids[0];
+    let context_properties = ContextProperties::new().platform(platform_id);
+    let context =
+        ocl_core::create_context(Some(&context_properties), &[device_id], None, None).unwrap();
+    let queue = ocl_core::create_command_queue(&context, &device_id, None).unwrap();
+    let dims = [8, 1, 1];
+
+    // Create a `Buffer`:
+    let mut vec = vec![0.0f32; dims[0]];
+    let buffer = unsafe {
+        ocl_core::create_buffer(
+            &context,
+            ocl_core::MEM_READ_WRITE | ocl_core::MEM_COPY_HOST_PTR,
+            dims[0],
+            Some(&vec),
+        )
+        .unwrap()
+    };
+    ocl_core::finish(&queue).unwrap(); //sync up before switching to arrayfire
+
+    // Add custom device, context and associated queue to ArrayFire
+    afcl::add_device_context(device_id.as_raw(), context.as_ptr(), queue.as_ptr());
+    afcl::set_device_context(device_id.as_raw(), context.as_ptr());
+    af::info();
+
+    let mut af_buffer = af::Array::new_from_device_ptr(
+        buffer.as_ptr() as *mut f32,
+        af::Dim4::new(&[dims[0] as u64, 1, 1, 1]),
+    );
+
+    af::af_print!("GPU Buffer before modification:", af_buffer);
+
+    af_buffer = af_buffer + 10f32;
+
+    af::sync(af::get_device());
+    unsafe {
+        let ptr = af_buffer.device_ptr();
+        let obuf = ocl_core::Mem::from_raw_copied_ptr(ptr);
+
+        // Read results from the device into a vector:
+        ocl_core::enqueue_read_buffer(
+            &queue,
+            &obuf,
+            true,
+            0,
+            &mut vec,
+            None::<Event>,
+            None::<&mut Event>,
+        )
+        .unwrap();
+    }
+    println!("GPU buffer on host after ArrayFire operation: {:?}", vec);
+
+    // Remove device from ArrayFire management towards Application Exit
+    af::set_device(0); // Cannot pop when in Use, hence switch to another device
+    afcl::delete_device_context(device_id.as_raw(), context.as_ptr());
+}
+
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/print.html b/book/print.html new file mode 100644 index 000000000..5955b139c --- /dev/null +++ b/book/print.html @@ -0,0 +1,1663 @@ + + + + + + Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

ArrayFire is a high performance software library for parallel computing with an easy-to-use API. +ArrayFire abstracts away much of the details of programming parallel architectures by providing +a high-level container object, the Array, that represents data stored on a CPU, GPU, FPGA, +or other type of accelerator. This abstraction permits developers to write massively parallel +applications in a high-level language where they need not be concerned about low-level optimizations +that are frequently required to achieve high throughput on most parallel architectures.

+

Supported data types

+

ArrayFire provides one generic container object, the Array on which functions and mathematical +operations are performed. The Array can represent one of many different basic data types:

+
    +
  • F32 real single-precision (float)
  • +
  • C32 complex single-precision (cfloat)
  • +
  • F64 real double-precision (double)
  • +
  • C64 complex double-precision (cdouble)
  • +
  • B8 8-bit boolean values (bool)
  • +
  • S32 32-bit signed integer (int)
  • +
  • U32 32-bit unsigned integer (unsigned)
  • +
  • U8 8-bit unsigned values (unsigned char)
  • +
  • S64 64-bit signed integer (intl)
  • +
  • U64 64-bit unsigned integer (uintl)
  • +
  • S16 16-bit signed integer (short)
  • +
  • U16 16-bit unsigned integer (unsigned short)
  • +
  • F16 16-bit floating point number (half::f16)
  • +
+

Most of these data types are supported on all modern GPUs; however, some older devices may lack +support for double precision arrays. In this case, a runtime error will be generated when the array +is constructed.

+

If not specified, Arrays are created as single precision floating point numbers (F32).

+

Creating and populating an Array

+

ArrayFire Array's represent memory stored on the device. As such, creation and population of +an array will consume memory on the device which cannot freed until the array object goes out of +scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which +will re-use device memory whenever possible.

+

Arrays can be created using one of the array constructors. Below we show how to create 1D, 2D, +and 3D arrays with uninitialized values:

+
let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32);
+
+

However, uninitialized memory is likely not useful in your application. ArrayFire provides several +convenient functions for creating arrays that contain pre-populated values including constants, +uniform random numbers, uniform normally distributed numbers, and the identity matrix:

+
// Create an array filled with constant value of 2.0 of type floating point
+// The type of Array is infered from the type of the constant argument
+let cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1]));
+print(&cnst);
+
+
println!("Create a 5-by-3 matrix of random floats on the GPU");
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<f32>(dims);
+print(&a);
+
+

As stated above, the default data type for arrays is F32(32-bit floating point number) unless +specified otherwise.

+

ArrayFire Arrays may also be populated from data found on the host. For example:

+
let values: [u32; 3] = [1u32, 2, 3];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

Properties of an Array

+

ArrayFire provides several functions to determine various aspects of arrays. This includes +functions to print the contents, query dimensions, and determine various other aspects of arrays.

+

The print function can be used to print arrays that have already been generated or any +expression involving arrays:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+print(&indices);
+
+

The dimensions of an array may be determined using either a Dim4 object or by accessing the +dimensions directly using the Dim4::get and Dim4::numdims functions:

+
let values: [f32; 3] = [1.0, 2.0, 3.0];
+let dims: Dim4 = Dim4::new(&[3, 1, 1, 1]);
+let indices = Array::new(&values, dims);
+println!("Dims {:?} with dimensions {}", dims.get(), dims.ndims());
+
+

In addition to dimensions, arrays also carry several properties including methods to determine the +underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, +a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you +consult the full documentation on the Array.

+

Writing math expressions using ArrayFire

+

ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions +using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, +ArrayFire functions like a vector library. That means that an element-wise operation, like +c[i] = a[i] + b[i] in C, would be written more concisely without indexing, like c = a + b. When +there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. +his "kernel fusion" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations.

+

Our JIT functionality extends across C API boundary and only ends when a non-JIT function is +encountered or a synchronization operation is explicitly called by the code.

+

ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators +(e.g. +,-,*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples:

+
let num_rows: u64 = 5;
+let num_cols: u64 = 3;
+let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
+let a = randu::<f32>(dims);
+let b = randu::<f32>(dims);
+print(&a);
+print(&b);
+let c = a + b;
+print(&c);
+
+//Example of *Assign traits
+let mut d = randu::<f32>(dims);
+let e     = constant(1f32, dims);
+d += e;
+print(&d);
+
+

Indexing

+

Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To +index Arrays you may use one or a combination of the following functions:

+ +

Please see the indexing page for several examples of how to use these functions.

+

Access to Array memory on the host

+

Memory in af::Arrays may be accessed using the Array::host() method. The host function +copies the data from the device and makes it available in a standard slice or similar container on +the host. As such, it is up to the developer to manage any memory returned by host.

+ +

Bitwise operators

+

In addition to supporting standard mathematical functions, Arrays that contain integer data types +also support bitwise operators including and, or, and shift etc. Operator traits for Array as well +as separate functions are also defined to support various use cases.

+
let dims = Dim4::new(&[5, 3, 1, 1]);
+let a = randu::<bool>(dims);
+let b = randu::<bool>(dims);
+
+print(&a);
+print(&b);
+
+let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid
+let d = bitand(&a, &b, false);
+
+print(&c);
+print(&d);
+
+

Where to go for help?

+ +

Vectorization

+

Programmers and Data Scientists want to take advantage of fast and parallel computational devices. +Writing vectorized code is necessary to get the best performance out of the current generation +parallel hardware and scientific computing software. However, writing vectorized code may not be +immediately intuitive. ArrayFire provides many ways to vectorize a given code segment. In this +chapter, we present several methods to vectorize code using ArrayFire and discuss the benefits and +drawbacks associated with each method.

+

Generic/Default vectorization

+

By its very nature, ArrayFire is a vectorized library. Most functions operate on Arrays as a whole +i.e. on all elements in parallel. For example consider the following code:

+
let mut a = af::range(Dim::new(&[10, 1, 1, 1]));  // [0,  9]
+a = a + 1;                                        // [1, 10]
+
+

This code will result in a single kernel that operates on all 10 elements of a in parallel.

+

A small subset of such vectorized ArrayFire functions are given below for quick reference:

+ + + + + + + + +
Operator CategoryFunctions
Arithmetic operations+, -, *, /, %, >>, <<
Logical operations&&, ||, <, >, ==, != etc.
Numeric functionsabs, floor, round, min, max, etc.
Complex operationsreal, imag, conjg, etc.
Exponential and logarithmic fnsexp, log, expm1, log1p, etc.
Trigonometric functionssin, cos, tan, etc.
Hyperbolic functionssinh, cosh, tanh, etc.
+

In addition to element-wise operations, many other functions are also vectorized in ArrayFire.

+

Notice that even functions that perform some form of aggregation (e.g. sum or min), +signal processing (like convolve), and image processing functions (i.e. rotate etc.)

+
    +
  • all support vectorization on different columns or images.
  • +
+

For example, if we have NUM images of size WIDTHxHEIGHT, one could convolve each image in a +vector fashion as follows:

+
let g_coef: [f32, 9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
+
+let f = Array::new(g_coef, Dim4::new(&[3, 3, 1, 1]));
+let filter = f * 1.0f32/16;
+
+let signal = randu(WIDTH, HEIGHT, NUM);
+let conv   = convolve2(signal, filter, ConvMode::DEFAULT, ConvDomain::AUTO);
+
+

Similarly, one can rotate 100 images by 45 degrees in a single call using code like the following:

+
// Construct an array of 100 WIDTH x HEIGHT images of random numbers
+let imgs = randu(WIDTH, HEIGHT, 100);
+
+// Rotate all of the images in a single command
+let rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR);
+
+

Although most functions in ArrayFire do support vectorization, some do not. Most notably, all +linear algebra functions. Even though they are not vectorized linear algebra operations, they still +execute in parallel on your hardware.

+

Using the built in vectorized operations should be the first and preferred method of vectorizing any +code written with ArrayFire.

+

GFOR

+

This construct is similar to gfor loop from C++ API of ArrayFire. It has not been implemented in +rust wrapper. This section will be updated once the feature has been added to the crate.

+

batch_func

+

This another pending feature that is similar to our C++ API of batchFunc()

+

Array and Matrix Manipulation

+

ArrayFire provides several different methods for manipulating arrays and matrices. The functionality +includes:

+
    +
  • moddims() - change the dimensions of an array without changing the data
  • +
  • flat() - flatten an array to one dimension
  • +
  • flip() - flip an array along a dimension
  • +
  • join() - join up to 4 arrays
  • +
  • reorder() - changes the dimension order within the array
  • +
  • shift() - shifts data along a dimension
  • +
  • tile() - repeats an array along a dimension
  • +
  • transpose() - performs a matrix transpose
  • +
+

Below we provide several examples of these functions and their use.

+

moddims()

+

The moddims function changes the dimensions of an array without changing its data or order. +Note that this function modifies only the metadata associated with the array. It does not modify +the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and +then back to a 8x1:

+
a [8 1 1 1]
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+
+let new_dims = Dim4::new(&[2, 4, 1, 1]);
+moddims(&a, new_dims)
+[2 4 1 1]
+    1.0000     1.0000     1.0000     1.0000
+    2.0000     2.0000     2.0000     2.0000
+
+let out = moddims(&a, a.elements(), 1, 1, 1);
+[8 1 1 1]
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+    1.0000
+    2.0000
+
+

flat()

+

The flat function flattens an array to one dimension:

+
a [3 3 1 1]
+    1.0000     4.0000     7.0000
+    2.0000     5.0000     8.0000
+    3.0000     6.0000     9.0000
+
+flat(&a)
+[9 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+    6.0000
+    7.0000
+    8.0000
+    9.0000
+
+

flip()

+

The flip function flips the contents of an array along a chosen dimension. In the example +below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. +across rows) axes:

+
a [5 2 1 1]
+    1.0000     6.0000
+    2.0000     7.0000
+    3.0000     8.0000
+    4.0000     9.0000
+    5.0000    10.0000
+
+flip(a, 0) [5 2 1 1]
+    5.0000    10.0000
+    4.0000     9.0000
+    3.0000     8.0000
+    2.0000     7.0000
+    1.0000     6.0000
+
+flip(a, 1) [5 2 1 1]
+    6.0000     1.0000
+    7.0000     2.0000
+    8.0000     3.0000
+    9.0000     4.0000
+   10.0000     5.0000
+
+

join()

+

The join, join_many functions can be used to join arrays along a specific dimension.

+

Here is an example of how to use join an array to itself:

+
a [5 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+
+join(0, a, a) [10 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+    1.0000
+    2.0000
+    3.0000
+    4.0000
+    5.0000
+
+join(1, a, a) [5 2 1 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+    4.0000     4.0000
+    5.0000     5.0000
+
+

reorder()

+

The reorder function modifies the order of data within an array by exchanging data according to +the change in dimensionality. The linear ordering of data within the array is preserved.

+
a [2 2 3 1]
+    1.0000     3.0000
+    2.0000     4.0000
+
+    1.0000     3.0000
+    2.0000     4.0000
+
+    1.0000     3.0000
+    2.0000     4.0000
+
+
+reorder(&a, 1, 0, 2)
+[2 2 3 1]  //equivalent to a transpose
+    1.0000     2.0000
+    3.0000     4.0000
+
+    1.0000     2.0000
+    3.0000     4.0000
+
+    1.0000     2.0000
+    3.0000     4.0000
+
+
+reorder(&a, 2, 0, 1)
+[3 2 2 1]
+    1.0000     2.0000
+    1.0000     2.0000
+    1.0000     2.0000
+
+    3.0000     4.0000
+    3.0000     4.0000
+    3.0000     4.0000
+
+

shift()

+

The shift function shifts data in a circular buffer fashion along a chosen dimension. Consider +the following example:

+
a [3 5 1 1]
+    0.0000     0.0000     0.0000     0.0000     0.0000
+    3.0000     4.0000     5.0000     1.0000     2.0000
+    3.0000     4.0000     5.0000     1.0000     2.0000
+
+shift(&a, 0, 2 )
+[3 5 1 1]
+    0.0000     0.0000     0.0000     0.0000     0.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+
+shift(&a, -1, 2 )
+[3 5 1 1]
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    1.0000     2.0000     3.0000     4.0000     5.0000
+    0.0000     0.0000     0.0000     0.0000     0.0000
+
+

tile()

+

The tile function repeats an array along the specified dimension. For example below we show how +to tile an array along the zeroth and first dimensions of an array:

+
a [3 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+
+// Repeat array a twice in the zeroth dimension
+tile(&a, 2)
+[6 1 1 1]
+    1.0000
+    2.0000
+    3.0000
+    1.0000
+    2.0000
+    3.0000
+
+// Repeat array a twice along both the zeroth and first dimensions
+tile(&a, 2, 2)
+[6 2 1 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+// Repeat array a twice along the first and three times along the second
+// dimension.
+let tile_dims = Dim4::new(&[1, 2, 3, 1]);
+tile(a, tile_dims) [3 2 3 1]
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+    1.0000     1.0000
+    2.0000     2.0000
+    3.0000     3.0000
+
+

transpose()

+

The transpose function performs a standard matrix transpose. The input array must have the +dimensions of a 2D-matrix.

+
a [3 3 1 1]
+    1.0000     3.0000     3.0000
+    2.0000     1.0000     3.0000
+    2.0000     2.0000     1.0000
+
+transpose(&a, False) //Second parameter to be used for conjugate transpose
+[3 3 1 1]
+    1.0000     2.0000     2.0000
+    3.0000     1.0000     2.0000
+    3.0000     3.0000     1.0000
+
+

Combining functions to enumerate grid coordinates

+

By using a combination of the functions, one can quickly code complex manipulation patterns with +a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis +goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small +combination of the above functions.

+
let a      = iota::<u32>(Dim4::new(&[3, 1, 1, 1]),
+                         Dim4::new(&[1, 3, 1, 1]));
+let b      = transpose(&a, false);
+let coords = join(1, &flat(&a), &flat(&b));
+print(&coords);
+
+

The output for a [3 3 1 1] matrix will be the following.

+
[9 2 1 1]
+         0          0
+         1          0
+         2          0
+         0          1
+         1          1
+         2          1
+         0          2
+         1          2
+         2          2
+
+

Indexing

+

Indexing in ArrayFire is a powerful but easy to abuse feature. This feature allows you to reference +or copy subsections of a larger array and perform operations on only a subset of elements.

+

This chapter is split into the following sections:

+ +

Indexer structure is the key element used in Rust wrapper of ArrayFire for creating references +to existing Arrays. The above sections illustrate how it can be used in conjunction with Seq +and/or Array. Apart from that, each section also showcases a macro based equivalent +code(if one exists) that is more terse in syntax but offers the same functionality.

+

Using Seq objects

+

Create a view of an existing Array

+

We will Sequences and the function index in this approach.

+
        let dims = Dim4::new(&[5, 5, 1, 1]);
+        let a = randu::<f32>(dims);
+        //af_print!("a", a);
+        //a
+        //[5 5 1 1]
+        //    0.3990     0.5160     0.8831     0.9107     0.6688
+        //    0.6720     0.3932     0.0621     0.9159     0.8434
+        //    0.5339     0.2706     0.7089     0.0231     0.1328
+        //    0.1386     0.9455     0.9434     0.2330     0.2657
+        //    0.7353     0.1587     0.1227     0.2220     0.2299
+
+        // Index array using sequences
+        let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
+        let _sub = index(&a, seqs);
+        //af_print!("a(seq(1,3,1), span)", sub);
+        // [3 5 1 1]
+        //     0.6720     0.3932     0.0621     0.9159     0.8434
+        //     0.5339     0.2706     0.7089     0.0231     0.1328
+        //     0.1386     0.9455     0.9434     0.2330     0.2657
+
+

However, the same above code can be condensed into a much terse syntax with the help of view +macro. Take a look at the following two approaches using view macro.

+
        let dims = dim4!(5, 5, 1, 1);
+        let a = randu::<f32>(dims);
+        let first3 = seq!(1:3:1);
+        let allindim2 = seq!();
+        let _sub = view!(a[first3, allindim2]);
+
+
OR
+
        let a = randu::<f32>(dim4!(5, 5));
+        let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis
+
+
+

Modify a sub region of an existing Array

+

Let us take a look at an example where a portion of an existing Array will be set to with another +Array. We will an constant value Array and the function assign_seq in the below example.

+
        let mut a = constant(2.0 as f32, dim4!(5, 3));
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+
+        let b = constant(1.0 as f32, dim4!(3, 3));
+        let seqs = [seq!(1:3:1), seq!()];
+        assign_seq(&mut a, &seqs, &b);
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 2.0 2.0 2.0
+
+

A much terser way of doing the same using macro is shown below

+
        let mut a = randu::<f32>(dim4!(5, 5));
+        let b = randu::<f32>(dim4!(2, 2));
+        eval!(a[1:2:1, 1:2:1] = b);
+
+
+

NOTE Normally you want to avoid accessing individual elements of the array like this for performance reasons.

+
+

Using Array and Seq combination

+

Create a view of an existing Array

+

To use a combination of Array and Seq objects to index an existing Array, we will need a more +generalized function index_gen.

+
        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = Seq::new(0.0, 2.0, 1.0);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        // [5 3 1 1]
+        //     0.0000     0.2190     0.3835
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+        //     0.5328     0.9347     0.0535
+
+        let mut idxrs = Indexer::default();
+        idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+        idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+        let _sub2 = index_gen(&a, idxrs);
+        //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+        // [3 3 1 1]
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+
+

Similar to how view macro helped with abreviating the syntax when indexing with just +sequences, it can also help when using a combination of Seq and Array.

+
        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = seq!(0:2:1);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        let _sub2 = view!(a[indices, seq4gen]);
+
+

Modify a sub region of an existing Array

+

Set a portion of an existing Array with another Array using a combination of Seq and Array. +We will use assign_gen function to do it.

+
       let values: [f32; 3] = [1.0, 2.0, 3.0];
+       let indices = Array::new(&values, dim4!(3, 1, 1, 1));
+       let seq4gen = seq!(0:2:1);
+       let mut a = randu::<f32>(dim4!(5, 3, 1, 1));
+       // [5 3 1 1]
+       //     0.0000     0.2190     0.3835
+       //     0.1315     0.0470     0.5194
+       //     0.7556     0.6789     0.8310
+       //     0.4587     0.6793     0.0346
+       //     0.5328     0.9347     0.0535
+
+       let b = constant(2.0 as f32, dim4!(3, 3, 1, 1));
+
+       let mut idxrs = Indexer::default();
+       idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+       idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+       let _sub2 = assign_gen(&mut a, &idxrs, &b);
+       //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+       // [5 3 1 1]
+       //     0.0000     0.2190     0.3835
+       //     2.0000     2.0000     2.0000
+       //     2.0000     2.0000     2.0000
+       //     2.0000     2.0000     2.0000
+       //     0.5328     0.9347     0.0535
+
+
OR
+
       let values: [f32; 3] = [1.0, 2.0, 3.0];
+       let indices = Array::new(&values, dim4!(3));
+       let seq4gen = seq!(0:2:1);
+       let mut a = randu::<f32>(dim4!(5, 3));
+
+       let b = constant(2.0 as f32, dim4!(3, 3));
+
+       eval!(a[indices, seq4gen] = b);
+
+

Extract or Set rows/columns of an Array

+

Extract a specific set of rows/coloumns from an existing Array.

+
        let a = randu::<f32>(dim4!(5, 5, 1, 1));
+        //print(&a);
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, 4);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, 4);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+
+

You can also use rows & cols to retrieve a subset of rows or coloumns respectively.

+

Similarly, set_row & set_rows can be used to change the values in a particular set of +rows using another Array. set_col & set_cols has same functionality, except that it is +for coloumns.

+

Negative Indices

+

Negative indices can also be used to refer elements from the end of a given axis. Negative value for +a row/column/slice will fetch corresponding row/column/slice in reverse order. Given below are some +examples that showcase getting row(s)/col(s) from an existing Array.

+
        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, -1);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, -1);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+
+
        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = rows(&a, -1, -2);
+        // [2 5 1 1]
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = cols(&a, -1, -3);
+        // [5 3 1 1]
+        //     0.1583     0.3636     0.6755
+        //     0.3712     0.4165     0.6105
+        //     0.3543     0.5814     0.5232
+        //     0.6450     0.8962     0.5567
+        //     0.9675     0.3712     0.7896
+
+

Configuring Arrayfire Environment

+

Following are the list of environment and runtime configurations that will help enhance your +experience with ArrayFire.

+

AF_PATH

+

This is the path with ArrayFire gets installed, ie. the includes and libs are present in this +directory. You can use this variable to add include paths and libraries to your projects.

+

AF_PRINT_ERRORS

+

When AF\_PRINT\_ERRORS is set to 1, the exceptions thrown are more verbose and detailed. This +helps in locating the exact failure.

+
AF_PRINT_ERRORS=1 ./myprogram
+
+

AF_CUDA_DEFAULT_DEVICE

+

Use this variable to set the default CUDA device. Valid values for this variable are the device +identifiers shown when info is run.

+
AF_CUDA_DEFAULT_DEVICE=1 ./myprogram
+
+

Note: set_device call in the source code will take precedence over this variable.

+

AF_OPENCL_DEFAULT_DEVICE

+

Use this variable to set the default OpenCL device. Valid values for this variable are the device +identifiers shown when info is run.

+
AF_OPENCL_DEFAULT_DEVICE=1 ./myprogram
+
+

Note: set_device call in the source code will take precedence over this variable.

+

AF_OPENCL_DEFAULT_DEVICE_TYPE

+

Use this variable to set the default OpenCL device type. Valid values for this variable are: CPU, +GPU, ACC (Accelerators). When set, the first device of the specified type is chosen as default device.

+
AF_OPENCL_DEFAULT_DEVICE_TYPE=CPU ./myprogram
+
+

Note: AF_OPENCL_DEFAULT_DEVICE and set_device takes precedence over this variable.

+

AF_OPENCL_DEVICE_TYPE

+

Use this variable to only choose OpenCL devices of specified type. Valid values for this variable are:

+
    +
  • ALL: All OpenCL devices. (Default behavior).
  • +
  • CPU: CPU devices only.
  • +
  • GPU: GPU devices only.
  • +
  • ACC: Accelerator devices only.
  • +
+

When set, the remaining OpenCL device types are ignored by the OpenCL backend.

+
AF_OPENCL_DEVICE_TYPE=CPU ./myprogram
+
+

AF_OPENCL_CPU_OFFLOAD

+

When ArrayFire runs on devices with unified memory with the host (ie. CL_DEVICE_HOST_UNIFIED_MENORY +is true for the device) then certain functions are offloaded to run on the CPU using mapped buffers.

+

ArrayFire takes advantage of fast libraries such as MKL while spending no time copying memory from +device to host. The device memory is mapped to a host pointer which can be used in the offloaded +functions.

+

This functionality can be disabled by using the environment variable AF_OPENCL_CPU_OFFLOAD=0.

+

The default bevaior of this has changed in version 3.4. Prior to v3.4, CPU Offload functionality was +used only when the user set AF_OPENCL_CPU_OFFLOAD=1 and disabled otherwise. From v3.4 onwards, CPU +Offload is enabled by default and is disabled only when AF_OPENCL_CPU_OFFLOAD=0 is set.

+

AF_OPENCL_SHOW_BUILD_INFO

+

This variable is useful when debuggin OpenCL kernel compilation failures. When this variable is set +to 1, and an error occurs during a OpenCL kernel compilation, then the log and kernel are printed to screen.

+

AF_DISABLE_GRAPHICS

+

Setting this variable to 1 will disable window creation when graphics functions are being called. +Disabling window creation will disable all other graphics calls at runtime. This is a useful +when running code on servers and systems without displays. When graphics calls are run on such +machines, they will print warning about window creation failing. To suppress those calls, set this +variable.

+

AF_SYNCHRONOUS_CALLS

+

When this environment variable is set to 1, ArrayFire will execute all functions synchronously.

+

AF_SHOW_LOAD_PATH

+

When using the Unified backend, if this variable is set to 1, it will show the path where the ArrayFire +backend libraries are loaded from.

+

If the libraries are loaded from system paths, such as PATH or LD_LIBRARY_PATH etc, then it will +print "system path". If the libraries are loaded from other paths, then those paths are shown in full.

+

AF_MEM_DEBUG

+

When AF_MEM_DEBUG is set to 1 (or anything not equal to 0), the caching mechanism in the memory manager +is disabled. The device buffers are allocated using native functions as needed and freed when going out +of scope. When the environment variable is not set, it is treated to be non zero.

+
AF_MEM_DEBUG=1 ./myprogram
+
+

AF_MAX_BUFFERS

+

When AF_MAX_BUFFERS is set, this environment variable specifies the maximum number of buffers +allocated before garbage collection kicks in. Please note that the total number of buffers that +can exist simultaneously can be higher than this number. This variable tells the garbage collector +that it should free any available buffers immediately if the treshold is reached. When not set, +the default value is 1000.

+

AF_OPENCL_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum height of the OpenCL JIT tree after +which evaluation is forced. The default value, as of v3.4, is 50 on OSX, 100 everywhere else. +This value was 20 for older versions.

+

AF_CUDA_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum height of the CUDA JIT tree after +which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.

+

AF_CPU_MAX_JIT_LEN

+

When set, this environment variable specifies the maximum length of the CPU JIT tree after +which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.

+

Interoperability with CUDA

+

Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom +kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to +increase your productivity, or you may need to supplement ArrayFire's functionality with your own +custom implementation of specific algorithms.

+

ArrayFire manages its own memory, runs within its own CUDA stream, and creates custom IDs for +devices. As such, most of the interoperability functions focus on reducing potential synchronization +conflicts between ArrayFire and CUDA.

+

Basics

+

It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides +several functions to ease this process including:

+ + + + + + + + + + +
FunctionPurpose
Array::new_from_device_ptrConstruct an ArrayFire Array from device memory
Array::device_ptrObtain a pointer to the device memory (implies lock())
Array::lockRemoves ArrayFire's control of a device memory pointer
Array::unlockRestores ArrayFire's control over a device memory pointer
get_deviceGets the current ArrayFire device ID
set_deviceSwitches ArrayFire to the specified device
get_device_native_idFetches CUDA deviceID for a given ArrayFire device ID
set_device_native_idSwitches active device to the specified CUDA device ID
get_streamGet the current CUDA stream used by ArrayFire
+

Using custom CUDA kernels in existing ArrayFire application

+

By default, ArrayFire manages its own memory and operates in its own CUDA stream. Thus there is a +slight amount of bookkeeping that needs to be done in order to integrate your custom CUDA kernel.

+

Ideally, we recommend using ArrayFire's CUDA stream to launch your custom kernels. However, this +is currently not possible due to limitation on RustaCUDA not being to able to wrap an +existing cudaStream_t/CUstream_t objects. The current work around is to create a stream of your +own and launch the kernel on it.

+

Notice that since ArrayFire and your kernels are not sharing the same CUDA stream, there is a need +to perform explicit synchronization before launching kernel on your stream that depends on the +computation carried out by ArrayFire earlier. This extra step is unnecessary once the above stated +limiation of RustaCUDA's stream is eliminated.

+

This process is best illustrated with a fully worked example:

+
use arrayfire as af;
+use rustacuda::prelude::*;
+use rustacuda::*;
+
+use std::ffi::CString;
+
+fn main() {
+    // MAKE SURE to do all rustacuda initilization before arrayfire API's
+    // first call. It seems like some CUDA context state is getting messed up
+    // if we mix CUDA context init(device, context, module, stream) with ArrayFire API
+    match rustacuda::init(CudaFlags::empty()) {
+        Ok(()) => {}
+        Err(e) => panic!("rustacuda init failure: {:?}", e),
+    }
+    let device = match Device::get_device(0) {
+        Ok(d) => d,
+        Err(e) => panic!("Failed to get device: {:?}", e),
+    };
+    let _context =
+        match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) {
+            Ok(c) => c,
+            Err(e) => panic!("Failed to create context: {:?}", e),
+        };
+    let ptx = CString::new(include_str!("./resources/add.ptx")).unwrap();
+    let module = match Module::load_from_string(&ptx) {
+        Ok(m) => m,
+        Err(e) => panic!("Failed to load module from string: {:?}", e),
+    };
+    let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) {
+        Ok(s) => s,
+        Err(e) => panic!("Failed to create stream: {:?}", e),
+    };
+
+    af::set_device(0);
+    af::info();
+
+    let num: i32 = 10;
+    let x = af::constant(1f32, af::dim4!(10));
+    let y = af::constant(2f32, af::dim4!(10));
+    let out = af::constant(0f32, af::dim4!(10));
+
+    af::af_print!("x", x);
+    af::af_print!("y", y);
+    af::af_print!("out(init)", out);
+
+    //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda
+    // let af_id = get_device();
+    // let cuda_id = get_device_native_id(af_id);
+    // let af_cuda_stream = get_stream(cuda_id);
+
+    //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda
+    // let stream = Stream {inner: mem::transmute(af_cuda_stream)};
+
+    // Run a custom CUDA kernel in the ArrayFire CUDA stream
+    unsafe {
+        // Obtain device pointers from ArrayFire using Array::device() method
+        let d_x: *mut f32 = x.device_ptr() as *mut f32;
+        let d_y: *mut f32 = y.device_ptr() as *mut f32;
+        let d_o: *mut f32 = out.device_ptr() as *mut f32;
+
+        match launch!(module.sum<<<1, 1, 0, stream>>>(
+        memory::DevicePointer::wrap(d_x),
+        memory::DevicePointer::wrap(d_y),
+        memory::DevicePointer::wrap(d_o),
+        num
+        )) {
+            Ok(()) => {}
+            Err(e) => panic!("Kernel Launch failure: {:?}", e),
+        }
+
+        // wait for the kernel to finish as it is async call
+        match stream.synchronize() {
+            Ok(()) => {}
+            Err(e) => panic!("Stream sync failure: {:?}", e),
+        };
+
+        // Return control of Array memory to ArrayFire using unlock
+        x.unlock();
+        y.unlock();
+        out.unlock();
+    }
+    af::af_print!("sum after kernel launch", out);
+}
+
+
+

Adding ArrayFire to existing CUDA Application

+

Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due +to several optimizations we implement. The most important are as follows:

+
    +
  • ArrayFire assumes control of all memory provided to it.
  • +
  • ArrayFire does not (in general) support in-place memory transactions.
  • +
+

We will discuss the implications of these items below. To add ArrayFire to existing code you need to:

+
    +
  1. Finish any pending CUDA operations (e.g. cudaDeviceSynchronize() or similar stream functions)
  2. +
  3. Create ArrayFire arrays from existing CUDA pointers
  4. +
  5. Perform operations on ArrayFire arrays
  6. +
  7. Instruct ArrayFire to finish operations using eval and sync
  8. +
  9. Obtain pointers to important memory
  10. +
  11. Continue your CUDA application.
  12. +
  13. Free non-managed memory
  14. +
+

To create the Array fom device pointer, you should use one of the following approaches:

+

Using DeviceBuffer from RustaCUDA, or a Wrapper Object for CUDA device memory

+

+# #![allow(unused_variables)]
+#fn main() {
+let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap();
+
+let array_dptr = Array::new_from_device_ptr(
+    buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10));
+
+array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership
+#}
+

Using raw pointer returned from cuda_malloc interface exposed by RustaCUDA

+

+# #![allow(unused_variables)]
+#fn main() {
+let mut dptr: *mut f32 = std::ptr::null_mut();
+unsafe {
+    dptr = memory::cuda_malloc::<f32>(10*10).unwrap().as_raw_mut();
+}
+
+let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));
+// After ArrayFire takes over ownership of the pointer, you can use other
+// arrayfire functions as usual.
+#}
+

ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. +Thus ArrayFire could free or reuse the memory at any later time. If this behavior is not desired, +you may call Array::unlock and manage the memory yourself. However, if you do so, please be +cautious not to free memory when ArrayFire might be using it!

+

The seven steps above are best illustrated using a fully-worked example:

+
use arrayfire::{af_print, dim4, info, set_device, Array};
+use rustacuda::prelude::*;
+
+fn main() {
+    // MAKE SURE to do all rustacuda initilization before arrayfire API's
+    // first call. It seems like some CUDA context state is getting messed up
+    // if we mix CUDA context init(device, context, module, stream) with ArrayFire API
+    match rustacuda::init(CudaFlags::empty()) {
+        Ok(()) => {}
+        Err(e) => panic!("rustacuda init failure: {:?}", e),
+    }
+    let device = match Device::get_device(0) {
+        Ok(d) => d,
+        Err(e) => panic!("Failed to get device: {:?}", e),
+    };
+    let _context =
+        match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) {
+            Ok(c) => c,
+            Err(e) => panic!("Failed to create context: {:?}", e),
+        };
+    let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) {
+        Ok(s) => s,
+        Err(e) => panic!("Failed to create stream: {:?}", e),
+    };
+
+    let mut in_x = DeviceBuffer::from_slice(&[1.0f32; 10]).unwrap();
+    let mut in_y = DeviceBuffer::from_slice(&[2.0f32; 10]).unwrap();
+
+    // wait for any prior kernels to finish before passing
+    // the device pointers to ArrayFire
+    match stream.synchronize() {
+        Ok(()) => {}
+        Err(e) => panic!("Stream sync failure: {:?}", e),
+    };
+
+    set_device(0);
+    info();
+
+    let x = Array::new_from_device_ptr(in_x.as_device_ptr().as_raw_mut(), dim4!(10));
+    let y = Array::new_from_device_ptr(in_y.as_device_ptr().as_raw_mut(), dim4!(10));
+
+    // Lock so that ArrayFire doesn't free pointers from RustaCUDA
+    // But we have to make sure these pointers stay in valid scope
+    // as long as the associated ArrayFire Array objects are valid
+    x.lock();
+    y.lock();
+
+    af_print!("x", x);
+    af_print!("y", y);
+
+    let o = x + y;
+    af_print!("out", o);
+
+    let _o_dptr = unsafe { o.device_ptr() }; // Calls an implicit lock
+
+    // User has to call unlock if they want to relenquish control to ArrayFire
+
+    // Once the non-arrayfire operations are done, call unlock.
+    o.unlock(); // After this, there is no guarantee that value of o_dptr is valid
+}
+
+
+

Interoperability with OpenCL

+

Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom +kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to +increase your productivity, or you may need to supplement ArrayFire's functionality with your own +custom implementation of specific algorithms.

+

ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. As such, most +of the interoperability functions focus on reducing potential synchronization conflicts between +ArrayFire and OpenCL.

+

Basics

+

It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides +several functions to ease this process including:

+ + + + + + + + + + + + + +
FunctionPurpose
Array::new_from_device_ptrConstruct an ArrayFire Array from cl_mem
Array::device_ptrObtain a pointer to the device memory (implies lock)
Array::lockRemoves ArrayFire's control of a device memory pointer
Array::unlockRestores ArrayFire's control over a device memory pointer
get_platformGet ArrayFire's current cl_platform
get_deviceGets the current ArrayFire device ID
get_device_idGet ArrayFire's current cl_device_id
set_device_idSet ArrayFire's device from a cl_device_id
set_deviceSwitches ArrayFire to the specified device
get_contextGet ArrayFire's current cl_context
get_queueGet ArrayFire's current cl_command_queue
get_device_typeGet the current DeviceType
+

Note that the pointer returned by Array::device_ptr should be cast to cl_mem before using +it with OpenCL opaque types. The pointer is a cl_mem internally that is force casted to pointer +type by ArrayFire before returning the value to caller.

+

Additionally, the OpenCL backend permits the programmer to add and remove custom devices from the +ArrayFire device manager. These permit you to attach ArrayFire directly to the OpenCL queue used by +other portions of your application.

+ + + + +
FunctionPurpose
add_device_contextAdd a new device to ArrayFire's device manager
set_device_contextSet ArrayFire's device from cl_device_id & cl_context
delete_device_contextRemove a device from ArrayFire's device manager
+

Below we provide two worked examples on how ArrayFire can be integrated +into new and existing projects.

+

Adding custom OpenCL kernels to an existing ArrayFire application

+

By default, ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. +Thus there is some bookkeeping that needs to be done to integrate your custom OpenCL kernel.

+

If your kernels can share operate in the same queue as ArrayFire, you should:

+
    +
  1. Obtain the OpenCL context, device, and queue used by ArrayFire
  2. +
  3. Obtain cl_mem references to Array objects
  4. +
  5. Load, build, and use your kernels
  6. +
  7. Return control of Array memory to ArrayFire
  8. +
+

Note, ArrayFire uses an in-order queue, thus when ArrayFire and your kernels are operating in the +same queue, there is no need to perform any synchronization operations.

+

This process is best illustrated with a fully worked example:

+
//! A trivial example. Copied from ocl-core crate repository.
+use af_opencl_interop as afcl;
+use arrayfire as af;
+
+use ocl_core::{ArgVal, Event};
+
+use std::ffi::CString;
+
+fn main() {
+    af::info();
+    let dims = af::dim4!(8);
+    let af_buffer = af::constant(0f32, dims.clone());
+    af::af_print!("af_buffer", af_buffer);
+
+    let src = r#"
+        __kernel void add(__global float* buffer, float scalar) {
+            buffer[get_global_id(0)] += scalar;
+        }
+    "#;
+
+    let af_did = afcl::get_device_id();
+    let af_ctx = afcl::get_context(false);
+    let af_que = afcl::get_queue(false);
+
+    let _devid = unsafe { ocl_core::DeviceId::from_raw(af_did) };
+    let contx = unsafe { ocl_core::Context::from_raw_copied_ptr(af_ctx) };
+    let queue = unsafe { ocl_core::CommandQueue::from_raw_copied_ptr(af_que) };
+
+    // Define which platform and device(s) to use. Create a context,
+    // queue, and program then define some dims..
+    let src_cstring = CString::new(src).unwrap();
+    let program = ocl_core::create_program_with_source(&contx, &[src_cstring]).unwrap();
+    ocl_core::build_program(
+        &program,
+        None::<&[()]>,
+        &CString::new("").unwrap(),
+        None,
+        None,
+    )
+    .unwrap();
+
+    // Fetch cl_mem from ArrayFire Array
+    let ptr = unsafe { af_buffer.device_ptr() };
+    let buffer = unsafe { ocl_core::Mem::from_raw_copied_ptr(ptr) };
+
+    // Create a kernel with arguments matching those in the source above:
+    let kernel = ocl_core::create_kernel(&program, "add").unwrap();
+    ocl_core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap();
+    ocl_core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap();
+
+    let ocl_dims: [usize; 3] = [dims[0] as usize, dims[1] as usize, dims[2] as usize];
+    unsafe {
+        ocl_core::enqueue_kernel(
+            &queue,
+            &kernel,
+            1,
+            None,
+            &ocl_dims,
+            None,
+            None::<Event>,
+            None::<&mut Event>,
+        )
+        .unwrap();
+    }
+    ocl_core::finish(&queue).unwrap();
+    af_buffer.unlock(); //Give back control of cl_mem to ArrayFire memory manager
+
+    af::af_print!("af_buffer after running Custom Kernel on it", af_buffer);
+}
+
+
+

If your kernels needs to operate in their own OpenCL queue, the process is essentially identical, +except you need to instruct ArrayFire to complete its computations using the sync function +prior to launching your own kernel and ensure your kernels are complete using clFinish +(or similar) commands prior to returning control of the memory to ArrayFire:

+
    +
  1. Obtain the OpenCL context, device, and queue used by ArrayFire
  2. +
  3. Obtain cl_mem references to Array objects
  4. +
  5. Instruct ArrayFire to finish operations using sync
  6. +
  7. Load, build, and use your kernels
  8. +
  9. Instruct OpenCL to finish operations using clFinish() or similar commands.
  10. +
  11. Return control of Array memory to ArrayFire
  12. +
+

Adding ArrayFire to an existing OpenCL application

+

Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due +to several optimizations we implement. The most important are as follows:

+
    +
  • ArrayFire assumes control of all memory provided to it.
  • +
  • ArrayFire does not (in general) support in-place memory transactions.
  • +
+

We will discuss the implications of these items below. To add ArrayFire to existing code you need to:

+
    +
  1. Instruct OpenCL to complete its operations using clFinish (or similar)
  2. +
  3. Instruct ArrayFire to use the user-created OpenCL Context
  4. +
  5. Create ArrayFire arrays from OpenCL memory objects
  6. +
  7. Perform ArrayFire operations on the Arrays
  8. +
  9. Instruct ArrayFire to finish operations using sync
  10. +
  11. Obtain cl_mem references for important memory
  12. +
  13. Continue your OpenCL application
  14. +
+ +
+

ArrayFire's memory manager automatically assumes responsibility for any memory provided to +it. If you are creating an array from another RAII style object, you should retain it to ensure +your memory is not deallocated if your RAII object were to go out of scope.

+
+
+

If you do not wish for ArrayFire to manage your memory, you may call the Array::unlock +function and manage the memory yourself; however, if you do so, please be cautious not to call +clReleaseMemObj on a cl_mem when ArrayFire might be using it!

+
+

Given below is a fully working example:

+
//! A trivial example. Copied from ocl-core crate repository.
+use af_opencl_interop as afcl;
+use arrayfire as af;
+
+use ocl_core::{ContextProperties, Event};
+
+fn main() {
+    // Choose platform & device(s) to use. Create a context, queue,
+    let platform_id = ocl_core::default_platform().unwrap();
+    let device_ids = ocl_core::get_device_ids(&platform_id, None, None).unwrap();
+    let device_id = device_ids[0];
+    let context_properties = ContextProperties::new().platform(platform_id);
+    let context =
+        ocl_core::create_context(Some(&context_properties), &[device_id], None, None).unwrap();
+    let queue = ocl_core::create_command_queue(&context, &device_id, None).unwrap();
+    let dims = [8, 1, 1];
+
+    // Create a `Buffer`:
+    let mut vec = vec![0.0f32; dims[0]];
+    let buffer = unsafe {
+        ocl_core::create_buffer(
+            &context,
+            ocl_core::MEM_READ_WRITE | ocl_core::MEM_COPY_HOST_PTR,
+            dims[0],
+            Some(&vec),
+        )
+        .unwrap()
+    };
+    ocl_core::finish(&queue).unwrap(); //sync up before switching to arrayfire
+
+    // Add custom device, context and associated queue to ArrayFire
+    afcl::add_device_context(device_id.as_raw(), context.as_ptr(), queue.as_ptr());
+    afcl::set_device_context(device_id.as_raw(), context.as_ptr());
+    af::info();
+
+    let mut af_buffer = af::Array::new_from_device_ptr(
+        buffer.as_ptr() as *mut f32,
+        af::Dim4::new(&[dims[0] as u64, 1, 1, 1]),
+    );
+
+    af::af_print!("GPU Buffer before modification:", af_buffer);
+
+    af_buffer = af_buffer + 10f32;
+
+    af::sync(af::get_device());
+    unsafe {
+        let ptr = af_buffer.device_ptr();
+        let obuf = ocl_core::Mem::from_raw_copied_ptr(ptr);
+
+        // Read results from the device into a vector:
+        ocl_core::enqueue_read_buffer(
+            &queue,
+            &obuf,
+            true,
+            0,
+            &mut vec,
+            None::<Event>,
+            None::<&mut Event>,
+        )
+        .unwrap();
+    }
+    println!("GPU buffer on host after ArrayFire operation: {:?}", vec);
+
+    // Remove device from ArrayFire management towards Application Exit
+    af::set_device(0); // Cannot pop when in Use, hence switch to another device
+    afcl::delete_device_context(device_id.as_raw(), context.as_ptr());
+}
+
+
+

ArrayFire in Threaded Applications

+

In this chapter, we will looking at how to use ArrayFire in multi-threaded programs. We shall +go over the details in the following order.

+ +

Move an Array to thread

+

In this section, we are going to create an Array on main thread and move it to a child thread, +modify it and then print it from the child thread.

+
        set_device(0);
+        info();
+        let mut a = constant(1, dim4!(3, 3));
+
+        let handle = thread::spawn(move || {
+            //set_device to appropriate device id is required in each thread
+            set_device(0);
+
+            println!("\nFrom thread {:?}", thread::current().id());
+
+            a += constant(2, dim4!(3, 3));
+            print(&a);
+        });
+
+        //Need to join other threads as main thread holds arrayfire context
+        handle.join().unwrap();
+
+

Read Array from Multiple threads

+

Now, let's expand the earlier example to do a bunch of arithmetic operations in parallel on +multiple threads using the same Array objects.

+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        // ArrayFire Array's are internally maintained via atomic reference counting
+        // Thus, they need no Arc wrapping while moving to another thread.
+        // Just call clone method on the object and share the resulting clone object
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+                thread::spawn(move || {
+                    set_device(0); //Both of objects are created on device 0 earlier
+                    match op {
+                        Op::Add => {
+                            let _c = x + y;
+                        }
+                        Op::Sub => {
+                            let _c = x - y;
+                        }
+                        Op::Div => {
+                            let _c = x / y;
+                        }
+                        Op::Mul => {
+                            let _c = x * y;
+                        }
+                    }
+                    sync(0);
+                    thread::sleep(std::time::Duration::new(1, 0));
+                })
+            })
+            .collect();
+        for child in threads {
+            let _ = child.join();
+        }
+
+

Given below is the definition of the enum Op we used in the example for illustration simplicity.

+
    #[derive(Debug, Copy, Clone)]
+    enum Op {
+        Add,
+        Sub,
+        Div,
+        Mul,
+    }
+
+

Write to Array from Multiple threads

+

Let us further expand the earlier example by accumulating the results of the arithmetic operations +into a single Array object.

+

The code will differ from earlier section in couple of locations:

+
    +
  • In the main thread, we wrap the accumulating Array in a read-write lock (std::sync::RwLock) +which is in turn wrapped in an atomically reference counted counter a.k.a std::sync::Arc.
  • +
  • In the children threads, we use the guarded objects returned by RwLock's write method to access +the accumulator Array.
  • +
+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        // Move ownership to RwLock and wrap in Arc since same object is to be modified
+        let c_lock = Arc::new(RwLock::new(c));
+
+        // a and b are internally reference counted by ArrayFire. Unless there
+        // is prior known need that they may be modified, you can simply clone
+        // the objects pass them to threads
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+
+                let wlock = c_lock.clone();
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+                    if let Ok(mut c_guard) = wlock.write() {
+                        match op {
+                            Op::Add => {
+                                *c_guard += x + y;
+                            }
+                            Op::Sub => {
+                                *c_guard += x - y;
+                            }
+                            Op::Div => {
+                                *c_guard += x / y;
+                            }
+                            Op::Mul => {
+                                *c_guard += x * y;
+                            }
+                        }
+                    }
+                })
+            })
+            .collect();
+
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //let read_guard = c_lock.read().unwrap();
+        //af_print!("C after threads joined", *read_guard);
+        //C after threads joined
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+
+

Write to single Array using Channel

+

In this section, we shall modify the example to use channel instead of data sharing.

+
        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+        let ops_len: usize = ops.len();
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let mut c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let (tx, rx) = mpsc::channel();
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                // a and b are internally reference counted by ArrayFire. Unless there
+                // is prior known need that they may be modified, you can simply clone
+                // the objects pass them to threads
+                let x = a.clone();
+                let y = b.clone();
+
+                let tx_clone = tx.clone();
+
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+
+                    let c = match op {
+                        Op::Add => x + y,
+                        Op::Sub => x - y,
+                        Op::Div => x / y,
+                        Op::Mul => x * y,
+                    };
+                    tx_clone.send(c).unwrap();
+                })
+            })
+            .collect();
+
+        for _i in 0..ops_len {
+            c += rx.recv().unwrap();
+        }
+
+        //Need to join other threads as main thread holds arrayfire context
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //af_print!("C after accumulating results", &c);
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/searcher.js b/book/searcher.js new file mode 100644 index 000000000..7fd97d487 --- /dev/null +++ b/book/searcher.js @@ -0,0 +1,477 @@ +"use strict"; +window.search = window.search || {}; +(function search(search) { + // Search functionality + // + // You can use !hasFocus() to prevent keyhandling in your key + // event handlers while the user is typing their search. + + if (!Mark || !elasticlunr) { + return; + } + + //IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; + } + + var search_wrap = document.getElementById('search-wrapper'), + searchbar = document.getElementById('searchbar'), + searchbar_outer = document.getElementById('searchbar-outer'), + searchresults = document.getElementById('searchresults'), + searchresults_outer = document.getElementById('searchresults-outer'), + searchresults_header = document.getElementById('searchresults-header'), + searchicon = document.getElementById('search-toggle'), + content = document.getElementById('content'), + + searchindex = null, + doc_urls = [], + results_options = { + teaser_word_count: 30, + limit_results: 30, + }, + search_options = { + bool: "AND", + expand: true, + fields: { + title: {boost: 1}, + body: {boost: 1}, + breadcrumbs: {boost: 0} + } + }, + mark_exclude = [], + marker = new Mark(content), + current_searchterm = "", + URL_SEARCH_PARAM = 'search', + URL_MARK_PARAM = 'highlight', + teaser_count = 0, + + SEARCH_HOTKEY_KEYCODE = 83, + ESCAPE_KEYCODE = 27, + DOWN_KEYCODE = 40, + UP_KEYCODE = 38, + SELECT_KEYCODE = 13; + + function hasFocus() { + return searchbar === document.activeElement; + } + + function removeChildren(elem) { + while (elem.firstChild) { + elem.removeChild(elem.firstChild); + } + } + + // Helper to parse a url into its building blocks. + function parseURL(url) { + var a = document.createElement('a'); + a.href = url; + return { + source: url, + protocol: a.protocol.replace(':',''), + host: a.hostname, + port: a.port, + params: (function(){ + var ret = {}; + var seg = a.search.replace(/^\?/,'').split('&'); + var len = seg.length, i = 0, s; + for (;i': '>', + '"': '"', + "'": ''' + }; + var repl = function(c) { return MAP[c]; }; + return function(s) { + return s.replace(/[&<>'"]/g, repl); + }; + })(); + + function formatSearchMetric(count, searchterm) { + if (count == 1) { + return count + " search result for '" + searchterm + "':"; + } else if (count == 0) { + return "No search results for '" + searchterm + "'."; + } else { + return count + " search results for '" + searchterm + "':"; + } + } + + function formatSearchResult(result, searchterms) { + var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms); + teaser_count++; + + // The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor + var url = doc_urls[result.ref].split("#"); + if (url.length == 1) { // no anchor found + url.push(""); + } + + return '' + result.doc.breadcrumbs + '' + + '' + + teaser + ''; + } + + function makeTeaser(body, searchterms) { + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + var stemmed_searchterms = searchterms.map(function(w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var searchterm_weight = 40; + var weighted = []; // contains elements of ["word", weight, index_in_document] + // split in sentences, then words + var sentences = body.toLowerCase().split('. '); + var index = 0; + var value = 0; + var searchterm_found = false; + for (var sentenceindex in sentences) { + var words = sentences[sentenceindex].split(' '); + value = 8; + for (var wordindex in words) { + var word = words[wordindex]; + if (word.length > 0) { + for (var searchtermindex in stemmed_searchterms) { + if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) { + value = searchterm_weight; + searchterm_found = true; + } + }; + weighted.push([word, value, index]); + value = 2; + } + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + }; + index += 1; // because we split at a two-char boundary '. ' + }; + + if (weighted.length == 0) { + return body; + } + + var window_weight = []; + var window_size = Math.min(weighted.length, results_options.teaser_word_count); + + var cur_sum = 0; + for (var wordindex = 0; wordindex < window_size; wordindex++) { + cur_sum += weighted[wordindex][1]; + }; + window_weight.push(cur_sum); + for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) { + cur_sum -= weighted[wordindex][1]; + cur_sum += weighted[wordindex + window_size][1]; + window_weight.push(cur_sum); + }; + + if (searchterm_found) { + var max_sum = 0; + var max_sum_window_index = 0; + // backwards + for (var i = window_weight.length - 1; i >= 0; i--) { + if (window_weight[i] > max_sum) { + max_sum = window_weight[i]; + max_sum_window_index = i; + } + }; + } else { + max_sum_window_index = 0; + } + + // add around searchterms + var teaser_split = []; + var index = weighted[max_sum_window_index][2]; + for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) { + var word = weighted[i]; + if (index < word[2]) { + // missing text from index to start of `word` + teaser_split.push(body.substring(index, word[2])); + index = word[2]; + } + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + index = word[2] + word[0].length; + teaser_split.push(body.substring(word[2], index)); + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + }; + + return teaser_split.join(''); + } + + function init(config) { + results_options = config.results_options; + search_options = config.search_options; + searchbar_outer = config.searchbar_outer; + doc_urls = config.doc_urls; + searchindex = elasticlunr.Index.load(config.index); + + // Set up events + searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false); + searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false); + document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false); + // If the user uses the browser buttons, do the same as if a reload happened + window.onpopstate = function(e) { doSearchOrMarkFromUrl(); }; + // Suppress "submit" events so the page doesn't reload when the user presses Enter + document.addEventListener('submit', function(e) { e.preventDefault(); }, false); + + // If reloaded, do the search or mark again, depending on the current url parameters + doSearchOrMarkFromUrl(); + } + + function unfocusSearchbar() { + // hacky, but just focusing a div only works once + var tmp = document.createElement('input'); + tmp.setAttribute('style', 'position: absolute; opacity: 0;'); + searchicon.appendChild(tmp); + tmp.focus(); + tmp.remove(); + } + + // On reload or browser history backwards/forwards events, parse the url and do search or mark + function doSearchOrMarkFromUrl() { + // Check current URL for search request + var url = parseURL(window.location.href); + if (url.params.hasOwnProperty(URL_SEARCH_PARAM) + && url.params[URL_SEARCH_PARAM] != "") { + showSearch(true); + searchbar.value = decodeURIComponent( + (url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20')); + searchbarKeyUpHandler(); // -> doSearch() + } else { + showSearch(false); + } + + if (url.params.hasOwnProperty(URL_MARK_PARAM)) { + var words = url.params[URL_MARK_PARAM].split(' '); + marker.mark(words, { + exclude: mark_exclude + }); + + var markers = document.querySelectorAll("mark"); + function hide() { + for (var i = 0; i < markers.length; i++) { + markers[i].classList.add("fade-out"); + window.setTimeout(function(e) { marker.unmark(); }, 300); + } + } + for (var i = 0; i < markers.length; i++) { + markers[i].addEventListener('click', hide); + } + } + } + + // Eventhandler for keyevents on `document` + function globalKeyHandler(e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea') { return; } + + if (e.keyCode === ESCAPE_KEYCODE) { + e.preventDefault(); + searchbar.classList.remove("active"); + setSearchUrlParameters("", + (searchbar.value.trim() !== "") ? "push" : "replace"); + if (hasFocus()) { + unfocusSearchbar(); + } + showSearch(false); + marker.unmark(); + } else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) { + e.preventDefault(); + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else if (hasFocus() && e.keyCode === DOWN_KEYCODE) { + e.preventDefault(); + unfocusSearchbar(); + searchresults.firstElementChild.classList.add("focus"); + } else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE + || e.keyCode === UP_KEYCODE + || e.keyCode === SELECT_KEYCODE)) { + // not `:focus` because browser does annoying scrolling + var focused = searchresults.querySelector("li.focus"); + if (!focused) return; + e.preventDefault(); + if (e.keyCode === DOWN_KEYCODE) { + var next = focused.nextElementSibling; + if (next) { + focused.classList.remove("focus"); + next.classList.add("focus"); + } + } else if (e.keyCode === UP_KEYCODE) { + focused.classList.remove("focus"); + var prev = focused.previousElementSibling; + if (prev) { + prev.classList.add("focus"); + } else { + searchbar.select(); + } + } else { // SELECT_KEYCODE + window.location.assign(focused.querySelector('a')); + } + } + } + + function showSearch(yes) { + if (yes) { + search_wrap.classList.remove('hidden'); + searchicon.setAttribute('aria-expanded', 'true'); + } else { + search_wrap.classList.add('hidden'); + searchicon.setAttribute('aria-expanded', 'false'); + var results = searchresults.children; + for (var i = 0; i < results.length; i++) { + results[i].classList.remove("focus"); + } + } + } + + function showResults(yes) { + if (yes) { + searchresults_outer.classList.remove('hidden'); + } else { + searchresults_outer.classList.add('hidden'); + } + } + + // Eventhandler for search icon + function searchIconClickHandler() { + if (search_wrap.classList.contains('hidden')) { + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else { + showSearch(false); + } + } + + // Eventhandler for keyevents while the searchbar is focused + function searchbarKeyUpHandler() { + var searchterm = searchbar.value.trim(); + if (searchterm != "") { + searchbar.classList.add("active"); + doSearch(searchterm); + } else { + searchbar.classList.remove("active"); + showResults(false); + removeChildren(searchresults); + } + + setSearchUrlParameters(searchterm, "push_if_new_search_else_replace"); + + // Remove marks + marker.unmark(); + } + + // Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor . + // `action` can be one of "push", "replace", "push_if_new_search_else_replace" + // and replaces or pushes a new browser history item. + // "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet. + function setSearchUrlParameters(searchterm, action) { + var url = parseURL(window.location.href); + var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM); + if (searchterm != "" || action == "push_if_new_search_else_replace") { + url.params[URL_SEARCH_PARAM] = searchterm; + delete url.params[URL_MARK_PARAM]; + url.hash = ""; + } else { + delete url.params[URL_SEARCH_PARAM]; + } + // A new search will also add a new history item, so the user can go back + // to the page prior to searching. A updated search term will only replace + // the url. + if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) { + history.pushState({}, document.title, renderURL(url)); + } else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) { + history.replaceState({}, document.title, renderURL(url)); + } + } + + function doSearch(searchterm) { + + // Don't search the same twice + if (current_searchterm == searchterm) { return; } + else { current_searchterm = searchterm; } + + if (searchindex == null) { return; } + + // Do the actual search + var results = searchindex.search(searchterm, search_options); + var resultcount = Math.min(results.length, results_options.limit_results); + + // Display search metrics + searchresults_header.innerText = formatSearchMetric(resultcount, searchterm); + + // Clear and insert results + var searchterms = searchterm.split(' '); + removeChildren(searchresults); + for(var i = 0; i < resultcount ; i++){ + var resultElem = document.createElement('li'); + resultElem.innerHTML = formatSearchResult(results[i], searchterms); + searchresults.appendChild(resultElem); + } + + // Display results + showResults(true); + } + + fetch(path_to_root + 'searchindex.json') + .then(response => response.json()) + .then(json => init(json)) + .catch(error => { // Try to load searchindex.js if fetch failed + var script = document.createElement('script'); + script.src = path_to_root + 'searchindex.js'; + script.onload = () => init(window.search); + document.head.appendChild(script); + }); + + // Exported functions + search.hasFocus = hasFocus; +})(window.search); diff --git a/book/searchindex.js b/book/searchindex.js new file mode 100644 index 000000000..07ff32967 --- /dev/null +++ b/book/searchindex.js @@ -0,0 +1 @@ +Object.assign(window.search, {"doc_urls":["getting_started.html#supported-data-types","getting_started.html#creating-and-populating-an-array","getting_started.html#properties-of-an-array","getting_started.html#writing-math-expressions-using-arrayfire","getting_started.html#indexing","getting_started.html#access-to-array-memory-on-the-host","getting_started.html#bitwise-operators","getting_started.html#where-to-go-for-help","vectorization.html#vectorization","vectorization.html#genericdefault-vectorization","vectorization.html#gfor","vectorization.html#batch_func","array_and_matrix_manipulation.html#array-and-matrix-manipulation","array_and_matrix_manipulation.html#moddims","array_and_matrix_manipulation.html#flat","array_and_matrix_manipulation.html#flip","array_and_matrix_manipulation.html#join","array_and_matrix_manipulation.html#reorder","array_and_matrix_manipulation.html#shift","array_and_matrix_manipulation.html#tile","array_and_matrix_manipulation.html#transpose","array_and_matrix_manipulation.html#combining-functions-to-enumerate-grid-coordinates","indexing.html#indexing","indexing.html#using-seq-objects","indexing.html#create-a-view-of-an-existing-array","indexing.html#modify-a-sub-region-of-an-existing-array","indexing.html#using-array-and-seq-combination","indexing.html#create-a-view-of-an-existing-array","indexing.html#modify-a-sub-region-of-an-existing-array","indexing.html#extract-or-set-rowscolumns-of-an-array","indexing.html#negative-indices","configuring_arrayfire_environment.html#configuring-arrayfire-environment","configuring_arrayfire_environment.html#af_path","configuring_arrayfire_environment.html#af_print_errors","configuring_arrayfire_environment.html#af_cuda_default_device","configuring_arrayfire_environment.html#af_opencl_default_device","configuring_arrayfire_environment.html#af_opencl_default_device_type","configuring_arrayfire_environment.html#af_opencl_device_type","configuring_arrayfire_environment.html#af_opencl_cpu_offload","configuring_arrayfire_environment.html#af_opencl_show_build_info","configuring_arrayfire_environment.html#af_disable_graphics","configuring_arrayfire_environment.html#af_synchronous_calls","configuring_arrayfire_environment.html#af_show_load_path","configuring_arrayfire_environment.html#af_mem_debug","configuring_arrayfire_environment.html#af_max_buffers","configuring_arrayfire_environment.html#af_opencl_max_jit_len","configuring_arrayfire_environment.html#af_cuda_max_jit_len","configuring_arrayfire_environment.html#af_cpu_max_jit_len","cuda-interop.html#interoperability-with-cuda","cuda-interop.html#basics","cuda-interop.html#using-custom-cuda-kernels-in-existing-arrayfire-application","cuda-interop.html#adding-arrayfire-to-existing-cuda-application","opencl-interop.html#interoperability-with-opencl","opencl-interop.html#basics","opencl-interop.html#adding-custom-opencl-kernels-to-an-existing-arrayfire-application","opencl-interop.html#adding-arrayfire-to-an-existing-opencl-application","multi-threading.html#arrayfire-in-threaded-applications","multi-threading.html#move-an-array-to-thread","multi-threading.html#read-array-from-multiple-threads","multi-threading.html#write-to-array-from-multiple-threads","multi-threading.html#write-to-single-array-using-channel"],"index":{"documentStore":{"docInfo":{"0":{"body":177,"breadcrumbs":3,"title":3},"1":{"body":153,"breadcrumbs":3,"title":3},"10":{"body":16,"breadcrumbs":1,"title":1},"11":{"body":7,"breadcrumbs":1,"title":1},"12":{"body":58,"breadcrumbs":3,"title":3},"13":{"body":76,"breadcrumbs":1,"title":1},"14":{"body":33,"breadcrumbs":1,"title":1},"15":{"body":69,"breadcrumbs":1,"title":1},"16":{"body":54,"breadcrumbs":1,"title":1},"17":{"body":76,"breadcrumbs":1,"title":1},"18":{"body":76,"breadcrumbs":1,"title":1},"19":{"body":107,"breadcrumbs":1,"title":1},"2":{"body":103,"breadcrumbs":2,"title":2},"20":{"body":44,"breadcrumbs":1,"title":1},"21":{"body":79,"breadcrumbs":5,"title":5},"22":{"body":90,"breadcrumbs":1,"title":1},"23":{"body":0,"breadcrumbs":3,"title":3},"24":{"body":115,"breadcrumbs":4,"title":4},"25":{"body":92,"breadcrumbs":5,"title":5},"26":{"body":0,"breadcrumbs":4,"title":4},"27":{"body":125,"breadcrumbs":4,"title":4},"28":{"body":126,"breadcrumbs":5,"title":5},"29":{"body":90,"breadcrumbs":4,"title":4},"3":{"body":127,"breadcrumbs":5,"title":5},"30":{"body":151,"breadcrumbs":2,"title":2},"31":{"body":9,"breadcrumbs":3,"title":3},"32":{"body":16,"breadcrumbs":1,"title":1},"33":{"body":14,"breadcrumbs":1,"title":1},"34":{"body":25,"breadcrumbs":1,"title":1},"35":{"body":25,"breadcrumbs":1,"title":1},"36":{"body":31,"breadcrumbs":1,"title":1},"37":{"body":33,"breadcrumbs":1,"title":1},"38":{"body":70,"breadcrumbs":1,"title":1},"39":{"body":20,"breadcrumbs":1,"title":1},"4":{"body":43,"breadcrumbs":1,"title":1},"40":{"body":39,"breadcrumbs":1,"title":1},"41":{"body":8,"breadcrumbs":1,"title":1},"42":{"body":30,"breadcrumbs":1,"title":1},"43":{"body":30,"breadcrumbs":1,"title":1},"44":{"body":36,"breadcrumbs":1,"title":1},"45":{"body":22,"breadcrumbs":1,"title":1},"46":{"body":19,"breadcrumbs":1,"title":1},"47":{"body":19,"breadcrumbs":1,"title":1},"48":{"body":52,"breadcrumbs":2,"title":2},"49":{"body":76,"breadcrumbs":1,"title":1},"5":{"body":25,"breadcrumbs":4,"title":4},"50":{"body":291,"breadcrumbs":7,"title":7},"51":{"body":332,"breadcrumbs":5,"title":5},"52":{"body":50,"breadcrumbs":2,"title":2},"53":{"body":152,"breadcrumbs":1,"title":1},"54":{"body":270,"breadcrumbs":7,"title":7},"55":{"body":263,"breadcrumbs":5,"title":5},"56":{"body":29,"breadcrumbs":3,"title":3},"57":{"body":45,"breadcrumbs":3,"title":3},"58":{"body":124,"breadcrumbs":4,"title":4},"59":{"body":182,"breadcrumbs":4,"title":4},"6":{"body":51,"breadcrumbs":2,"title":2},"60":{"body":144,"breadcrumbs":5,"title":5},"7":{"body":11,"breadcrumbs":2,"title":2},"8":{"body":51,"breadcrumbs":1,"title":1},"9":{"body":223,"breadcrumbs":2,"title":2}},"docs":{"0":{"body":"ArrayFire is a high performance software library for parallel computing with an easy-to-use API. ArrayFire abstracts away much of the details of programming parallel architectures by providing a high-level container object, the Array , that represents data stored on a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write massively parallel applications in a high-level language where they need not be concerned about low-level optimizations that are frequently required to achieve high throughput on most parallel architectures. ArrayFire provides one generic container object, the Array on which functions and mathematical operations are performed. The Array can represent one of many different basic data types : F32 real single-precision (float) C32 complex single-precision (cfloat) F64 real double-precision (double) C64 complex double-precision (cdouble) B8 8-bit boolean values (bool) S32 32-bit signed integer (int) U32 32-bit unsigned integer (unsigned) U8 8-bit unsigned values (unsigned char) S64 64-bit signed integer (intl) U64 64-bit unsigned integer (uintl) S16 16-bit signed integer (short) U16 16-bit unsigned integer (unsigned short) F16 16-bit floating point number ( half::f16 ) Most of these data types are supported on all modern GPUs; however, some older devices may lack support for double precision arrays. In this case, a runtime error will be generated when the array is constructed. If not specified, Arrays are created as single precision floating point numbers ( F32 ).","breadcrumbs":"Supported data types","id":"0","title":"Supported data types"},"1":{"body":"ArrayFire Array 's represent memory stored on the device. As such, creation and population of an array will consume memory on the device which cannot freed until the array object goes out of scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which will re-use device memory whenever possible. Arrays can be created using one of the array constructors . Below we show how to create 1D, 2D, and 3D arrays with uninitialized values: let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32); However, uninitialized memory is likely not useful in your application. ArrayFire provides several convenient functions for creating arrays that contain pre-populated values including constants, uniform random numbers, uniform normally distributed numbers, and the identity matrix: // Create an array filled with constant value of 2.0 of type floating point\n// The type of Array is infered from the type of the constant argument\nlet cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1]));\nprint(&cnst); println!(\"Create a 5-by-3 matrix of random floats on the GPU\");\nlet dims = Dim4::new(&[5, 3, 1, 1]);\nlet a = randu::(dims);\nprint(&a); As stated above, the default data type for arrays is F32 (32-bit floating point number) unless specified otherwise. ArrayFire Arrays may also be populated from data found on the host. For example: let values: [u32; 3] = [1u32, 2, 3];\nlet indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));\nprint(&indices);","breadcrumbs":"Creating and populating an Array","id":"1","title":"Creating and populating an Array"},"10":{"body":"This construct is similar to gfor loop from C++ API of ArrayFire. It has not been implemented in rust wrapper. This section will be updated once the feature has been added to the crate.","breadcrumbs":"GFOR","id":"10","title":"GFOR"},"11":{"body":"This another pending feature that is similar to our C++ API of batchFunc()","breadcrumbs":"batch_func","id":"11","title":"batch_func"},"12":{"body":"ArrayFire provides several different methods for manipulating arrays and matrices. The functionality includes: moddims() - change the dimensions of an array without changing the data flat() - flatten an array to one dimension flip() - flip an array along a dimension join() - join up to 4 arrays reorder() - changes the dimension order within the array shift() - shifts data along a dimension tile() - repeats an array along a dimension transpose() - performs a matrix transpose Below we provide several examples of these functions and their use.","breadcrumbs":"Array and Matrix Manipulation","id":"12","title":"Array and Matrix Manipulation"},"13":{"body":"The moddims function changes the dimensions of an array without changing its data or order. Note that this function modifies only the metadata associated with the array. It does not modify the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and then back to a 8x1: a [8 1 1 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 let new_dims = Dim4::new(&[2, 4, 1, 1]);\nmoddims(&a, new_dims)\n[2 4 1 1] 1.0000 1.0000 1.0000 1.0000 2.0000 2.0000 2.0000 2.0000 let out = moddims(&a, a.elements(), 1, 1, 1);\n[8 1 1 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000","breadcrumbs":"moddims()","id":"13","title":"moddims()"},"14":{"body":"The flat function flattens an array to one dimension: a [3 3 1 1] 1.0000 4.0000 7.0000 2.0000 5.0000 8.0000 3.0000 6.0000 9.0000 flat(&a)\n[9 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000","breadcrumbs":"flat()","id":"14","title":"flat()"},"15":{"body":"The flip function flips the contents of an array along a chosen dimension. In the example below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. across rows) axes: a [5 2 1 1] 1.0000 6.0000 2.0000 7.0000 3.0000 8.0000 4.0000 9.0000 5.0000 10.0000 flip(a, 0) [5 2 1 1] 5.0000 10.0000 4.0000 9.0000 3.0000 8.0000 2.0000 7.0000 1.0000 6.0000 flip(a, 1) [5 2 1 1] 6.0000 1.0000 7.0000 2.0000 8.0000 3.0000 9.0000 4.0000 10.0000 5.0000","breadcrumbs":"flip()","id":"15","title":"flip()"},"16":{"body":"The join , join_many functions can be used to join arrays along a specific dimension. Here is an example of how to use join an array to itself: a [5 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 join(0, a, a) [10 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 join(1, a, a) [5 2 1 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000","breadcrumbs":"join()","id":"16","title":"join()"},"17":{"body":"The reorder function modifies the order of data within an array by exchanging data according to the change in dimensionality. The linear ordering of data within the array is preserved. a [2 2 3 1] 1.0000 3.0000 2.0000 4.0000 1.0000 3.0000 2.0000 4.0000 1.0000 3.0000 2.0000 4.0000 reorder(&a, 1, 0, 2)\n[2 2 3 1] //equivalent to a transpose 1.0000 2.0000 3.0000 4.0000 1.0000 2.0000 3.0000 4.0000 1.0000 2.0000 3.0000 4.0000 reorder(&a, 2, 0, 1)\n[3 2 2 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 3.0000 4.0000 3.0000 4.0000 3.0000 4.0000","breadcrumbs":"reorder()","id":"17","title":"reorder()"},"18":{"body":"The shift function shifts data in a circular buffer fashion along a chosen dimension. Consider the following example: a [3 5 1 1] 0.0000 0.0000 0.0000 0.0000 0.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 shift(&a, 0, 2 )\n[3 5 1 1] 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 shift(&a, -1, 2 )\n[3 5 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 0.0000 0.0000 0.0000 0.0000 0.0000","breadcrumbs":"shift()","id":"18","title":"shift()"},"19":{"body":"The tile function repeats an array along the specified dimension. For example below we show how to tile an array along the zeroth and first dimensions of an array: a [3 1 1 1] 1.0000 2.0000 3.0000 // Repeat array a twice in the zeroth dimension\ntile(&a, 2)\n[6 1 1 1] 1.0000 2.0000 3.0000 1.0000 2.0000 3.0000 // Repeat array a twice along both the zeroth and first dimensions\ntile(&a, 2, 2)\n[6 2 1 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 // Repeat array a twice along the first and three times along the second\n// dimension.\nlet tile_dims = Dim4::new(&[1, 2, 3, 1]);\ntile(a, tile_dims) [3 2 3 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000","breadcrumbs":"tile()","id":"19","title":"tile()"},"2":{"body":"ArrayFire provides several functions to determine various aspects of arrays. This includes functions to print the contents, query dimensions, and determine various other aspects of arrays. The print function can be used to print arrays that have already been generated or any expression involving arrays: let values: [f32; 3] = [1.0, 2.0, 3.0];\nlet indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));\nprint(&indices); The dimensions of an array may be determined using either a Dim4 object or by accessing the dimensions directly using the Dim4::get and Dim4::numdims functions: let values: [f32; 3] = [1.0, 2.0, 3.0];\nlet dims: Dim4 = Dim4::new(&[3, 1, 1, 1]);\nlet indices = Array::new(&values, dims);\nprintln!(\"Dims {:?} with dimensions {}\", dims.get(), dims.ndims()); In addition to dimensions, arrays also carry several properties including methods to determine the underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you consult the full documentation on the Array .","breadcrumbs":"Properties of an Array","id":"2","title":"Properties of an Array"},"20":{"body":"The transpose function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix. a [3 3 1 1] 1.0000 3.0000 3.0000 2.0000 1.0000 3.0000 2.0000 2.0000 1.0000 transpose(&a, False) //Second parameter to be used for conjugate transpose\n[3 3 1 1] 1.0000 2.0000 2.0000 3.0000 1.0000 2.0000 3.0000 3.0000 1.0000","breadcrumbs":"transpose()","id":"20","title":"transpose()"},"21":{"body":"By using a combination of the functions, one can quickly code complex manipulation patterns with a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small combination of the above functions. let a = iota::(Dim4::new(&[3, 1, 1, 1]), Dim4::new(&[1, 3, 1, 1]));\nlet b = transpose(&a, false);\nlet coords = join(1, &flat(&a), &flat(&b));\nprint(&coords); The output for a [3 3 1 1] matrix will be the following. [9 2 1 1] 0 0 1 0 2 0 0 1 1 1 2 1 0 2 1 2 2 2","breadcrumbs":"Combining functions to enumerate grid coordinates","id":"21","title":"Combining functions to enumerate grid coordinates"},"22":{"body":"Indexing in ArrayFire is a powerful but easy to abuse feature. This feature allows you to reference or copy subsections of a larger array and perform operations on only a subset of elements. This chapter is split into the following sections: Index an Array using Seq Objects Create a view of an existing Array Modify a sub region of an existing Array Using Array and Seq combination Create a view of an existing Array Modify a sub region of an existing Array Extract or Set rows/columns of an Array Negative Indices Indexer structure is the key element used in Rust wrapper of ArrayFire for creating references to existing Arrays. The above sections illustrate how it can be used in conjunction with Seq and/or Array. Apart from that, each section also showcases a macro based equivalent code(if one exists) that is more terse in syntax but offers the same functionality.","breadcrumbs":"Indexing","id":"22","title":"Indexing"},"23":{"body":"","breadcrumbs":"Using Seq objects","id":"23","title":"Using Seq objects"},"24":{"body":"We will Sequences and the function index in this approach. let dims = Dim4::new(&[5, 5, 1, 1]); let a = randu::(dims); //af_print!(\"a\", a); //a //[5 5 1 1] // 0.3990 0.5160 0.8831 0.9107 0.6688 // 0.6720 0.3932 0.0621 0.9159 0.8434 // 0.5339 0.2706 0.7089 0.0231 0.1328 // 0.1386 0.9455 0.9434 0.2330 0.2657 // 0.7353 0.1587 0.1227 0.2220 0.2299 // Index array using sequences let seqs = &[Seq::new(1u32, 3, 1), Seq::default()]; let _sub = index(&a, seqs); //af_print!(\"a(seq(1,3,1), span)\", sub); // [3 5 1 1] // 0.6720 0.3932 0.0621 0.9159 0.8434 // 0.5339 0.2706 0.7089 0.0231 0.1328 // 0.1386 0.9455 0.9434 0.2330 0.2657 However, the same above code can be condensed into a much terse syntax with the help of view macro. Take a look at the following two approaches using view macro. let dims = dim4!(5, 5, 1, 1); let a = randu::(dims); let first3 = seq!(1:3:1); let allindim2 = seq!(); let _sub = view!(a[first3, allindim2]); OR let a = randu::(dim4!(5, 5)); let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis","breadcrumbs":"Create a view of an existing Array","id":"24","title":"Create a view of an existing Array"},"25":{"body":"Let us take a look at an example where a portion of an existing Array will be set to with another Array. We will an constant value Array and the function assign_seq in the below example. let mut a = constant(2.0 as f32, dim4!(5, 3)); //print(&a); // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 let b = constant(1.0 as f32, dim4!(3, 3)); let seqs = [seq!(1:3:1), seq!()]; assign_seq(&mut a, &seqs, &b); //print(&a); // 2.0 2.0 2.0 // 1.0 1.0 1.0 // 1.0 1.0 1.0 // 1.0 1.0 1.0 // 2.0 2.0 2.0 A much terser way of doing the same using macro is shown below let mut a = randu::(dim4!(5, 5)); let b = randu::(dim4!(2, 2)); eval!(a[1:2:1, 1:2:1] = b); NOTE Normally you want to avoid accessing individual elements of the array like this for performance reasons.","breadcrumbs":"Modify a sub region of an existing Array","id":"25","title":"Modify a sub region of an existing Array"},"26":{"body":"","breadcrumbs":"Using Array and Seq combination","id":"26","title":"Using Array and Seq combination"},"27":{"body":"To use a combination of Array and Seq objects to index an existing Array, we will need a more generalized function index_gen . let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); let seq4gen = Seq::new(0.0, 2.0, 1.0); let a = randu::(Dim4::new(&[5, 3, 1, 1])); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 // 0.5328 0.9347 0.0535 let mut idxrs = Indexer::default(); idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation let _sub2 = index_gen(&a, idxrs); //println!(\"a(indices, seq(0, 2, 1))\"); print(&sub2); // [3 3 1 1] // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 Similar to how view macro helped with abreviating the syntax when indexing with just sequences, it can also help when using a combination of Seq and Array. let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); let seq4gen = seq!(0:2:1); let a = randu::(Dim4::new(&[5, 3, 1, 1])); let _sub2 = view!(a[indices, seq4gen]);","breadcrumbs":"Create a view of an existing Array","id":"27","title":"Create a view of an existing Array"},"28":{"body":"Set a portion of an existing Array with another Array using a combination of Seq and Array. We will use assign_gen function to do it. let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, dim4!(3, 1, 1, 1)); let seq4gen = seq!(0:2:1); let mut a = randu::(dim4!(5, 3, 1, 1)); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 // 0.5328 0.9347 0.0535 let b = constant(2.0 as f32, dim4!(3, 3, 1, 1)); let mut idxrs = Indexer::default(); idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation let _sub2 = assign_gen(&mut a, &idxrs, &b); //println!(\"a(indices, seq(0, 2, 1))\"); print(&sub2); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 2.0000 2.0000 2.0000 // 2.0000 2.0000 2.0000 // 2.0000 2.0000 2.0000 // 0.5328 0.9347 0.0535 OR let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, dim4!(3)); let seq4gen = seq!(0:2:1); let mut a = randu::(dim4!(5, 3)); let b = constant(2.0 as f32, dim4!(3, 3)); eval!(a[indices, seq4gen] = b);","breadcrumbs":"Modify a sub region of an existing Array","id":"28","title":"Modify a sub region of an existing Array"},"29":{"body":"Extract a specific set of rows/coloumns from an existing Array. let a = randu::(dim4!(5, 5, 1, 1)); //print(&a); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = row(&a, 4); // [1 5 1 1] // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = col(&a, 4); // [5 1 1 1] // 0.6755 // 0.6105 // 0.5232 // 0.5567 // 0.7896 You can also use rows & cols to retrieve a subset of rows or coloumns respectively. Similarly, set_row & set_rows can be used to change the values in a particular set of rows using another Array. set_col & set_cols has same functionality, except that it is for coloumns.","breadcrumbs":"Extract or Set rows/columns of an Array","id":"29","title":"Extract or Set rows/columns of an Array"},"3":{"body":"ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, ArrayFire functions like a vector library. That means that an element-wise operation, like c[i] = a[i] + b[i] in C, would be written more concisely without indexing, like c = a + b. When there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. his \"kernel fusion\" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations. Our JIT functionality extends across C API boundary and only ends when a non-JIT function is encountered or a synchronization operation is explicitly called by the code. ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators (e.g. +,-,*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples: let num_rows: u64 = 5;\nlet num_cols: u64 = 3;\nlet dims = Dim4::new(&[num_rows, num_cols, 1, 1]);\nlet a = randu::(dims);\nlet b = randu::(dims);\nprint(&a);\nprint(&b);\nlet c = a + b;\nprint(&c); //Example of *Assign traits\nlet mut d = randu::(dims);\nlet e = constant(1f32, dims);\nd += e;\nprint(&d);","breadcrumbs":"Writing math expressions using ArrayFire","id":"3","title":"Writing math expressions using ArrayFire"},"30":{"body":"Negative indices can also be used to refer elements from the end of a given axis. Negative value for a row/column/slice will fetch corresponding row/column/slice in reverse order. Given below are some examples that showcase getting row(s)/col(s) from an existing Array. let a = randu::(dim4!(5, 5)); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = row(&a, -1); // [1 5 1 1] // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = col(&a, -1); // [5 1 1 1] // 0.6755 // 0.6105 // 0.5232 // 0.5567 // 0.7896 let a = randu::(dim4!(5, 5)); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = rows(&a, -1, -2); // [2 5 1 1] // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = cols(&a, -1, -3); // [5 3 1 1] // 0.1583 0.3636 0.6755 // 0.3712 0.4165 0.6105 // 0.3543 0.5814 0.5232 // 0.6450 0.8962 0.5567 // 0.9675 0.3712 0.7896","breadcrumbs":"Negative Indices","id":"30","title":"Negative Indices"},"31":{"body":"Following are the list of environment and runtime configurations that will help enhance your experience with ArrayFire.","breadcrumbs":"Configuring Arrayfire Environment","id":"31","title":"Configuring Arrayfire Environment"},"32":{"body":"This is the path with ArrayFire gets installed, ie. the includes and libs are present in this directory. You can use this variable to add include paths and libraries to your projects.","breadcrumbs":"AF_PATH","id":"32","title":"AF_PATH"},"33":{"body":"When AF\\_PRINT\\_ERRORS is set to 1, the exceptions thrown are more verbose and detailed. This helps in locating the exact failure. AF_PRINT_ERRORS=1 ./myprogram","breadcrumbs":"AF_PRINT_ERRORS","id":"33","title":"AF_PRINT_ERRORS"},"34":{"body":"Use this variable to set the default CUDA device. Valid values for this variable are the device identifiers shown when info is run. AF_CUDA_DEFAULT_DEVICE=1 ./myprogram Note: set_device call in the source code will take precedence over this variable.","breadcrumbs":"AF_CUDA_DEFAULT_DEVICE","id":"34","title":"AF_CUDA_DEFAULT_DEVICE"},"35":{"body":"Use this variable to set the default OpenCL device. Valid values for this variable are the device identifiers shown when info is run. AF_OPENCL_DEFAULT_DEVICE=1 ./myprogram Note: set_device call in the source code will take precedence over this variable.","breadcrumbs":"AF_OPENCL_DEFAULT_DEVICE","id":"35","title":"AF_OPENCL_DEFAULT_DEVICE"},"36":{"body":"Use this variable to set the default OpenCL device type. Valid values for this variable are: CPU, GPU, ACC (Accelerators). When set, the first device of the specified type is chosen as default device. AF_OPENCL_DEFAULT_DEVICE_TYPE=CPU ./myprogram Note: AF_OPENCL_DEFAULT_DEVICE and set_device takes precedence over this variable.","breadcrumbs":"AF_OPENCL_DEFAULT_DEVICE_TYPE","id":"36","title":"AF_OPENCL_DEFAULT_DEVICE_TYPE"},"37":{"body":"Use this variable to only choose OpenCL devices of specified type. Valid values for this variable are: ALL: All OpenCL devices. (Default behavior). CPU: CPU devices only. GPU: GPU devices only. ACC: Accelerator devices only. When set, the remaining OpenCL device types are ignored by the OpenCL backend. AF_OPENCL_DEVICE_TYPE=CPU ./myprogram","breadcrumbs":"AF_OPENCL_DEVICE_TYPE","id":"37","title":"AF_OPENCL_DEVICE_TYPE"},"38":{"body":"When ArrayFire runs on devices with unified memory with the host (ie. CL_DEVICE_HOST_UNIFIED_MENORY is true for the device) then certain functions are offloaded to run on the CPU using mapped buffers. ArrayFire takes advantage of fast libraries such as MKL while spending no time copying memory from device to host. The device memory is mapped to a host pointer which can be used in the offloaded functions. This functionality can be disabled by using the environment variable AF_OPENCL_CPU_OFFLOAD=0. The default bevaior of this has changed in version 3.4. Prior to v3.4, CPU Offload functionality was used only when the user set AF_OPENCL_CPU_OFFLOAD=1 and disabled otherwise. From v3.4 onwards, CPU Offload is enabled by default and is disabled only when AF_OPENCL_CPU_OFFLOAD=0 is set.","breadcrumbs":"AF_OPENCL_CPU_OFFLOAD","id":"38","title":"AF_OPENCL_CPU_OFFLOAD"},"39":{"body":"This variable is useful when debuggin OpenCL kernel compilation failures. When this variable is set to 1, and an error occurs during a OpenCL kernel compilation, then the log and kernel are printed to screen.","breadcrumbs":"AF_OPENCL_SHOW_BUILD_INFO","id":"39","title":"AF_OPENCL_SHOW_BUILD_INFO"},"4":{"body":"Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To index Arrays you may use one or a combination of the following functions: Seq representing a linear sequence Seq::Default() representing the entire dimension row(&Array, i) or col(&Array, i) specifying a single row/column rows(&Array, first,last) or cols(&Array, first,last) specifying a span of rows or columns Please see the indexing page for several examples of how to use these functions.","breadcrumbs":"Indexing","id":"4","title":"Indexing"},"40":{"body":"Setting this variable to 1 will disable window creation when graphics functions are being called. Disabling window creation will disable all other graphics calls at runtime. This is a useful when running code on servers and systems without displays. When graphics calls are run on such machines, they will print warning about window creation failing. To suppress those calls, set this variable.","breadcrumbs":"AF_DISABLE_GRAPHICS","id":"40","title":"AF_DISABLE_GRAPHICS"},"41":{"body":"When this environment variable is set to 1, ArrayFire will execute all functions synchronously.","breadcrumbs":"AF_SYNCHRONOUS_CALLS","id":"41","title":"AF_SYNCHRONOUS_CALLS"},"42":{"body":"When using the Unified backend, if this variable is set to 1, it will show the path where the ArrayFire backend libraries are loaded from. If the libraries are loaded from system paths, such as PATH or LD_LIBRARY_PATH etc, then it will print \"system path\". If the libraries are loaded from other paths, then those paths are shown in full.","breadcrumbs":"AF_SHOW_LOAD_PATH","id":"42","title":"AF_SHOW_LOAD_PATH"},"43":{"body":"When AF_MEM_DEBUG is set to 1 (or anything not equal to 0), the caching mechanism in the memory manager is disabled. The device buffers are allocated using native functions as needed and freed when going out of scope. When the environment variable is not set, it is treated to be non zero. AF_MEM_DEBUG=1 ./myprogram","breadcrumbs":"AF_MEM_DEBUG","id":"43","title":"AF_MEM_DEBUG"},"44":{"body":"When AF_MAX_BUFFERS is set, this environment variable specifies the maximum number of buffers allocated before garbage collection kicks in. Please note that the total number of buffers that can exist simultaneously can be higher than this number. This variable tells the garbage collector that it should free any available buffers immediately if the treshold is reached. When not set, the default value is 1000.","breadcrumbs":"AF_MAX_BUFFERS","id":"44","title":"AF_MAX_BUFFERS"},"45":{"body":"When set, this environment variable specifies the maximum height of the OpenCL JIT tree after which evaluation is forced. The default value, as of v3.4, is 50 on OSX, 100 everywhere else. This value was 20 for older versions.","breadcrumbs":"AF_OPENCL_MAX_JIT_LEN","id":"45","title":"AF_OPENCL_MAX_JIT_LEN"},"46":{"body":"When set, this environment variable specifies the maximum height of the CUDA JIT tree after which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.","breadcrumbs":"AF_CUDA_MAX_JIT_LEN","id":"46","title":"AF_CUDA_MAX_JIT_LEN"},"47":{"body":"When set, this environment variable specifies the maximum length of the CPU JIT tree after which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.","breadcrumbs":"AF_CPU_MAX_JIT_LEN","id":"47","title":"AF_CPU_MAX_JIT_LEN"},"48":{"body":"Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to increase your productivity, or you may need to supplement ArrayFire's functionality with your own custom implementation of specific algorithms. ArrayFire manages its own memory, runs within its own CUDA stream, and creates custom IDs for devices. As such, most of the interoperability functions focus on reducing potential synchronization conflicts between ArrayFire and CUDA.","breadcrumbs":"Interoperability with CUDA","id":"48","title":"Interoperability with CUDA"},"49":{"body":"It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides several functions to ease this process including: Function Purpose Array::new_from_device_ptr Construct an ArrayFire Array from device memory Array::device_ptr Obtain a pointer to the device memory (implies lock()) Array::lock Removes ArrayFire's control of a device memory pointer Array::unlock Restores ArrayFire's control over a device memory pointer get_device Gets the current ArrayFire device ID set_device Switches ArrayFire to the specified device get_device_native_id Fetches CUDA deviceID for a given ArrayFire device ID set_device_native_id Switches active device to the specified CUDA device ID get_stream Get the current CUDA stream used by ArrayFire","breadcrumbs":"Basics","id":"49","title":"Basics"},"5":{"body":"Memory in af::Arrays may be accessed using the Array::host() method. The host function copies the data from the device and makes it available in a standard slice or similar container on the host. As such, it is up to the developer to manage any memory returned by host.","breadcrumbs":"Access to Array memory on the host","id":"5","title":"Access to Array memory on the host"},"50":{"body":"By default, ArrayFire manages its own memory and operates in its own CUDA stream. Thus there is a slight amount of bookkeeping that needs to be done in order to integrate your custom CUDA kernel. Ideally, we recommend using ArrayFire's CUDA stream to launch your custom kernels. However, this is currently not possible due to limitation on RustaCUDA not being to able to wrap an existing cudaStream_t/CUstream_t objects. The current work around is to create a stream of your own and launch the kernel on it. Notice that since ArrayFire and your kernels are not sharing the same CUDA stream, there is a need to perform explicit synchronization before launching kernel on your stream that depends on the computation carried out by ArrayFire earlier. This extra step is unnecessary once the above stated limiation of RustaCUDA's stream is eliminated. This process is best illustrated with a fully worked example: use arrayfire as af;\nuse rustacuda::prelude::*;\nuse rustacuda::*; use std::ffi::CString; fn main() { // MAKE SURE to do all rustacuda initilization before arrayfire API's // first call. It seems like some CUDA context state is getting messed up // if we mix CUDA context init(device, context, module, stream) with ArrayFire API match rustacuda::init(CudaFlags::empty()) { Ok(()) => {} Err(e) => panic!(\"rustacuda init failure: {:?}\", e), } let device = match Device::get_device(0) { Ok(d) => d, Err(e) => panic!(\"Failed to get device: {:?}\", e), }; let _context = match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { Ok(c) => c, Err(e) => panic!(\"Failed to create context: {:?}\", e), }; let ptx = CString::new(include_str!(\"./resources/add.ptx\")).unwrap(); let module = match Module::load_from_string(&ptx) { Ok(m) => m, Err(e) => panic!(\"Failed to load module from string: {:?}\", e), }; let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { Ok(s) => s, Err(e) => panic!(\"Failed to create stream: {:?}\", e), }; af::set_device(0); af::info(); let num: i32 = 10; let x = af::constant(1f32, af::dim4!(10)); let y = af::constant(2f32, af::dim4!(10)); let out = af::constant(0f32, af::dim4!(10)); af::af_print!(\"x\", x); af::af_print!(\"y\", y); af::af_print!(\"out(init)\", out); //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda // let af_id = get_device(); // let cuda_id = get_device_native_id(af_id); // let af_cuda_stream = get_stream(cuda_id); //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda // let stream = Stream {inner: mem::transmute(af_cuda_stream)}; // Run a custom CUDA kernel in the ArrayFire CUDA stream unsafe { // Obtain device pointers from ArrayFire using Array::device() method let d_x: *mut f32 = x.device_ptr() as *mut f32; let d_y: *mut f32 = y.device_ptr() as *mut f32; let d_o: *mut f32 = out.device_ptr() as *mut f32; match launch!(module.sum<<<1, 1, 0, stream>>>( memory::DevicePointer::wrap(d_x), memory::DevicePointer::wrap(d_y), memory::DevicePointer::wrap(d_o), num )) { Ok(()) => {} Err(e) => panic!(\"Kernel Launch failure: {:?}\", e), } // wait for the kernel to finish as it is async call match stream.synchronize() { Ok(()) => {} Err(e) => panic!(\"Stream sync failure: {:?}\", e), }; // Return control of Array memory to ArrayFire using unlock x.unlock(); y.unlock(); out.unlock(); } af::af_print!(\"sum after kernel launch\", out);\n}","breadcrumbs":"Using custom CUDA kernels in existing ArrayFire application","id":"50","title":"Using custom CUDA kernels in existing ArrayFire application"},"51":{"body":"Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due to several optimizations we implement. The most important are as follows: ArrayFire assumes control of all memory provided to it. ArrayFire does not (in general) support in-place memory transactions. We will discuss the implications of these items below. To add ArrayFire to existing code you need to: Finish any pending CUDA operations (e.g. cudaDeviceSynchronize() or similar stream functions) Create ArrayFire arrays from existing CUDA pointers Perform operations on ArrayFire arrays Instruct ArrayFire to finish operations using eval and sync Obtain pointers to important memory Continue your CUDA application. Free non-managed memory To create the Array fom device pointer, you should use one of the following approaches: Using DeviceBuffer from RustaCUDA , or a Wrapper Object for CUDA device memory let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap(); let array_dptr = Array::new_from_device_ptr( buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10)); array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership Using raw pointer returned from cuda_malloc interface exposed by RustaCUDA let mut dptr: *mut f32 = std::ptr::null_mut();\nunsafe { dptr = memory::cuda_malloc::(10*10).unwrap().as_raw_mut();\n} let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));\n// After ArrayFire takes over ownership of the pointer, you can use other\n// arrayfire functions as usual. ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. Thus ArrayFire could free or reuse the memory at any later time. If this behavior is not desired, you may call Array::unlock and manage the memory yourself. However, if you do so, please be cautious not to free memory when ArrayFire might be using it! The seven steps above are best illustrated using a fully-worked example: use arrayfire::{af_print, dim4, info, set_device, Array};\nuse rustacuda::prelude::*; fn main() { // MAKE SURE to do all rustacuda initilization before arrayfire API's // first call. It seems like some CUDA context state is getting messed up // if we mix CUDA context init(device, context, module, stream) with ArrayFire API match rustacuda::init(CudaFlags::empty()) { Ok(()) => {} Err(e) => panic!(\"rustacuda init failure: {:?}\", e), } let device = match Device::get_device(0) { Ok(d) => d, Err(e) => panic!(\"Failed to get device: {:?}\", e), }; let _context = match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { Ok(c) => c, Err(e) => panic!(\"Failed to create context: {:?}\", e), }; let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { Ok(s) => s, Err(e) => panic!(\"Failed to create stream: {:?}\", e), }; let mut in_x = DeviceBuffer::from_slice(&[1.0f32; 10]).unwrap(); let mut in_y = DeviceBuffer::from_slice(&[2.0f32; 10]).unwrap(); // wait for any prior kernels to finish before passing // the device pointers to ArrayFire match stream.synchronize() { Ok(()) => {} Err(e) => panic!(\"Stream sync failure: {:?}\", e), }; set_device(0); info(); let x = Array::new_from_device_ptr(in_x.as_device_ptr().as_raw_mut(), dim4!(10)); let y = Array::new_from_device_ptr(in_y.as_device_ptr().as_raw_mut(), dim4!(10)); // Lock so that ArrayFire doesn't free pointers from RustaCUDA // But we have to make sure these pointers stay in valid scope // as long as the associated ArrayFire Array objects are valid x.lock(); y.lock(); af_print!(\"x\", x); af_print!(\"y\", y); let o = x + y; af_print!(\"out\", o); let _o_dptr = unsafe { o.device_ptr() }; // Calls an implicit lock // User has to call unlock if they want to relenquish control to ArrayFire // Once the non-arrayfire operations are done, call unlock. o.unlock(); // After this, there is no guarantee that value of o_dptr is valid\n}","breadcrumbs":"Adding ArrayFire to existing CUDA Application","id":"51","title":"Adding ArrayFire to existing CUDA Application"},"52":{"body":"Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to increase your productivity, or you may need to supplement ArrayFire's functionality with your own custom implementation of specific algorithms. ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. As such, most of the interoperability functions focus on reducing potential synchronization conflicts between ArrayFire and OpenCL.","breadcrumbs":"Interoperability with OpenCL","id":"52","title":"Interoperability with OpenCL"},"53":{"body":"It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides several functions to ease this process including: Function Purpose Array::new_from_device_ptr Construct an ArrayFire Array from cl_mem Array::device_ptr Obtain a pointer to the device memory (implies lock) Array::lock Removes ArrayFire's control of a device memory pointer Array::unlock Restores ArrayFire's control over a device memory pointer get_platform Get ArrayFire's current cl_platform get_device Gets the current ArrayFire device ID get_device_id Get ArrayFire's current cl_device_id set_device_id Set ArrayFire's device from a cl_device_id set_device Switches ArrayFire to the specified device get_context Get ArrayFire's current cl_context get_queue Get ArrayFire's current cl_command_queue get_device_type Get the current DeviceType Note that the pointer returned by Array::device_ptr should be cast to cl_mem before using it with OpenCL opaque types. The pointer is a cl_mem internally that is force casted to pointer type by ArrayFire before returning the value to caller. Additionally, the OpenCL backend permits the programmer to add and remove custom devices from the ArrayFire device manager. These permit you to attach ArrayFire directly to the OpenCL queue used by other portions of your application. Function Purpose add_device_context Add a new device to ArrayFire's device manager set_device_context Set ArrayFire's device from cl_device_id & cl_context delete_device_context Remove a device from ArrayFire's device manager Below we provide two worked examples on how ArrayFire can be integrated into new and existing projects.","breadcrumbs":"Basics","id":"53","title":"Basics"},"54":{"body":"By default, ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. Thus there is some bookkeeping that needs to be done to integrate your custom OpenCL kernel. If your kernels can share operate in the same queue as ArrayFire, you should: Obtain the OpenCL context, device, and queue used by ArrayFire Obtain cl_mem references to Array objects Load, build, and use your kernels Return control of Array memory to ArrayFire Note, ArrayFire uses an in-order queue, thus when ArrayFire and your kernels are operating in the same queue, there is no need to perform any synchronization operations. This process is best illustrated with a fully worked example: //! A trivial example. Copied from ocl-core crate repository.\nuse af_opencl_interop as afcl;\nuse arrayfire as af; use ocl_core::{ArgVal, Event}; use std::ffi::CString; fn main() { af::info(); let dims = af::dim4!(8); let af_buffer = af::constant(0f32, dims.clone()); af::af_print!(\"af_buffer\", af_buffer); let src = r#\" __kernel void add(__global float* buffer, float scalar) { buffer[get_global_id(0)] += scalar; } \"#; let af_did = afcl::get_device_id(); let af_ctx = afcl::get_context(false); let af_que = afcl::get_queue(false); let _devid = unsafe { ocl_core::DeviceId::from_raw(af_did) }; let contx = unsafe { ocl_core::Context::from_raw_copied_ptr(af_ctx) }; let queue = unsafe { ocl_core::CommandQueue::from_raw_copied_ptr(af_que) }; // Define which platform and device(s) to use. Create a context, // queue, and program then define some dims.. let src_cstring = CString::new(src).unwrap(); let program = ocl_core::create_program_with_source(&contx, &[src_cstring]).unwrap(); ocl_core::build_program( &program, None::<&[()]>, &CString::new(\"\").unwrap(), None, None, ) .unwrap(); // Fetch cl_mem from ArrayFire Array let ptr = unsafe { af_buffer.device_ptr() }; let buffer = unsafe { ocl_core::Mem::from_raw_copied_ptr(ptr) }; // Create a kernel with arguments matching those in the source above: let kernel = ocl_core::create_kernel(&program, \"add\").unwrap(); ocl_core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap(); ocl_core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap(); let ocl_dims: [usize; 3] = [dims[0] as usize, dims[1] as usize, dims[2] as usize]; unsafe { ocl_core::enqueue_kernel( &queue, &kernel, 1, None, &ocl_dims, None, None::, None::<&mut Event>, ) .unwrap(); } ocl_core::finish(&queue).unwrap(); af_buffer.unlock(); //Give back control of cl_mem to ArrayFire memory manager af::af_print!(\"af_buffer after running Custom Kernel on it\", af_buffer);\n} If your kernels needs to operate in their own OpenCL queue, the process is essentially identical, except you need to instruct ArrayFire to complete its computations using the sync function prior to launching your own kernel and ensure your kernels are complete using clFinish (or similar) commands prior to returning control of the memory to ArrayFire: Obtain the OpenCL context, device, and queue used by ArrayFire Obtain cl_mem references to Array objects Instruct ArrayFire to finish operations using sync Load, build, and use your kernels Instruct OpenCL to finish operations using clFinish() or similar commands. Return control of Array memory to ArrayFire","breadcrumbs":"Adding custom OpenCL kernels to an existing ArrayFire application","id":"54","title":"Adding custom OpenCL kernels to an existing ArrayFire application"},"55":{"body":"Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due to several optimizations we implement. The most important are as follows: ArrayFire assumes control of all memory provided to it. ArrayFire does not (in general) support in-place memory transactions. We will discuss the implications of these items below. To add ArrayFire to existing code you need to: Instruct OpenCL to complete its operations using clFinish (or similar) Instruct ArrayFire to use the user-created OpenCL Context Create ArrayFire arrays from OpenCL memory objects Perform ArrayFire operations on the Array s Instruct ArrayFire to finish operations using sync Obtain cl_mem references for important memory Continue your OpenCL application ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. If you are creating an array from another RAII style object, you should retain it to ensure your memory is not deallocated if your RAII object were to go out of scope. If you do not wish for ArrayFire to manage your memory, you may call the Array::unlock function and manage the memory yourself; however, if you do so, please be cautious not to call clReleaseMemObj on a cl_mem when ArrayFire might be using it! Given below is a fully working example: //! A trivial example. Copied from ocl-core crate repository.\nuse af_opencl_interop as afcl;\nuse arrayfire as af; use ocl_core::{ContextProperties, Event}; fn main() { // Choose platform & device(s) to use. Create a context, queue, let platform_id = ocl_core::default_platform().unwrap(); let device_ids = ocl_core::get_device_ids(&platform_id, None, None).unwrap(); let device_id = device_ids[0]; let context_properties = ContextProperties::new().platform(platform_id); let context = ocl_core::create_context(Some(&context_properties), &[device_id], None, None).unwrap(); let queue = ocl_core::create_command_queue(&context, &device_id, None).unwrap(); let dims = [8, 1, 1]; // Create a `Buffer`: let mut vec = vec![0.0f32; dims[0]]; let buffer = unsafe { ocl_core::create_buffer( &context, ocl_core::MEM_READ_WRITE | ocl_core::MEM_COPY_HOST_PTR, dims[0], Some(&vec), ) .unwrap() }; ocl_core::finish(&queue).unwrap(); //sync up before switching to arrayfire // Add custom device, context and associated queue to ArrayFire afcl::add_device_context(device_id.as_raw(), context.as_ptr(), queue.as_ptr()); afcl::set_device_context(device_id.as_raw(), context.as_ptr()); af::info(); let mut af_buffer = af::Array::new_from_device_ptr( buffer.as_ptr() as *mut f32, af::Dim4::new(&[dims[0] as u64, 1, 1, 1]), ); af::af_print!(\"GPU Buffer before modification:\", af_buffer); af_buffer = af_buffer + 10f32; af::sync(af::get_device()); unsafe { let ptr = af_buffer.device_ptr(); let obuf = ocl_core::Mem::from_raw_copied_ptr(ptr); // Read results from the device into a vector: ocl_core::enqueue_read_buffer( &queue, &obuf, true, 0, &mut vec, None::, None::<&mut Event>, ) .unwrap(); } println!(\"GPU buffer on host after ArrayFire operation: {:?}\", vec); // Remove device from ArrayFire management towards Application Exit af::set_device(0); // Cannot pop when in Use, hence switch to another device afcl::delete_device_context(device_id.as_raw(), context.as_ptr());\n}","breadcrumbs":"Adding ArrayFire to an existing OpenCL application","id":"55","title":"Adding ArrayFire to an existing OpenCL application"},"56":{"body":"In this chapter, we will looking at how to use ArrayFire in multi-threaded programs. We shall go over the details in the following order. Move an Array to thread Read Array from Multiple threads Write to Array from Multiple threads Write to single Array using Channel","breadcrumbs":"ArrayFire in Threaded Applications","id":"56","title":"ArrayFire in Threaded Applications"},"57":{"body":"In this section, we are going to create an Array on main thread and move it to a child thread, modify it and then print it from the child thread. set_device(0); info(); let mut a = constant(1, dim4!(3, 3)); let handle = thread::spawn(move || { //set_device to appropriate device id is required in each thread set_device(0); println!(\"\\nFrom thread {:?}\", thread::current().id()); a += constant(2, dim4!(3, 3)); print(&a); }); //Need to join other threads as main thread holds arrayfire context handle.join().unwrap();","breadcrumbs":"Move an Array to thread","id":"57","title":"Move an Array to thread"},"58":{"body":"Now, let's expand the earlier example to do a bunch of arithmetic operations in parallel on multiple threads using the same Array objects. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); // ArrayFire Array's are internally maintained via atomic reference counting // Thus, they need no Arc wrapping while moving to another thread. // Just call clone method on the object and share the resulting clone object let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); let threads: Vec<_> = ops .into_iter() .map(|op| { let x = a.clone(); let y = b.clone(); thread::spawn(move || { set_device(0); //Both of objects are created on device 0 earlier match op { Op::Add => { let _c = x + y; } Op::Sub => { let _c = x - y; } Op::Div => { let _c = x / y; } Op::Mul => { let _c = x * y; } } sync(0); thread::sleep(std::time::Duration::new(1, 0)); }) }) .collect(); for child in threads { let _ = child.join(); } Given below is the definition of the enum Op we used in the example for illustration simplicity. #[derive(Debug, Copy, Clone)] enum Op { Add, Sub, Div, Mul, }","breadcrumbs":"Read Array from Multiple threads","id":"58","title":"Read Array from Multiple threads"},"59":{"body":"Let us further expand the earlier example by accumulating the results of the arithmetic operations into a single Array object. The code will differ from earlier section in couple of locations: In the main thread, we wrap the accumulating Array in a read-write lock (std::sync::RwLock) which is in turn wrapped in an atomically reference counted counter a.k.a std::sync::Arc. In the children threads, we use the guarded objects returned by RwLock's write method to access the accumulator Array. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); let c = constant(0.0f32, dim4!(3, 3)); let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); // Move ownership to RwLock and wrap in Arc since same object is to be modified let c_lock = Arc::new(RwLock::new(c)); // a and b are internally reference counted by ArrayFire. Unless there // is prior known need that they may be modified, you can simply clone // the objects pass them to threads let threads: Vec<_> = ops .into_iter() .map(|op| { let x = a.clone(); let y = b.clone(); let wlock = c_lock.clone(); thread::spawn(move || { //Both of objects are created on device 0 in main thread //Every thread needs to set the device that it is going to //work on. Note that all Array objects must have been created //on same device as of date this is written on. set_device(0); if let Ok(mut c_guard) = wlock.write() { match op { Op::Add => { *c_guard += x + y; } Op::Sub => { *c_guard += x - y; } Op::Div => { *c_guard += x / y; } Op::Mul => { *c_guard += x * y; } } } }) }) .collect(); for child in threads { let _ = child.join(); } //let read_guard = c_lock.read().unwrap(); //af_print!(\"C after threads joined\", *read_guard); //C after threads joined //[3 3 1 1] // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000","breadcrumbs":"Write to Array from Multiple threads","id":"59","title":"Write to Array from Multiple threads"},"6":{"body":"In addition to supporting standard mathematical functions, Arrays that contain integer data types also support bitwise operators including and, or, and shift etc. Operator traits for Array as well as separate functions are also defined to support various use cases. let dims = Dim4::new(&[5, 3, 1, 1]);\nlet a = randu::(dims);\nlet b = randu::(dims); print(&a);\nprint(&b); let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid\nlet d = bitand(&a, &b, false); print(&c);\nprint(&d);","breadcrumbs":"Bitwise operators","id":"6","title":"Bitwise operators"},"60":{"body":"In this section, we shall modify the example to use channel instead of data sharing. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; let ops_len: usize = ops.len(); // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); let mut c = constant(0.0f32, dim4!(3, 3)); let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); let (tx, rx) = mpsc::channel(); let threads: Vec<_> = ops .into_iter() .map(|op| { // a and b are internally reference counted by ArrayFire. Unless there // is prior known need that they may be modified, you can simply clone // the objects pass them to threads let x = a.clone(); let y = b.clone(); let tx_clone = tx.clone(); thread::spawn(move || { //Both of objects are created on device 0 in main thread //Every thread needs to set the device that it is going to //work on. Note that all Array objects must have been created //on same device as of date this is written on. set_device(0); let c = match op { Op::Add => x + y, Op::Sub => x - y, Op::Div => x / y, Op::Mul => x * y, }; tx_clone.send(c).unwrap(); }) }) .collect(); for _i in 0..ops_len { c += rx.recv().unwrap(); } //Need to join other threads as main thread holds arrayfire context for child in threads { let _ = child.join(); } //af_print!(\"C after accumulating results\", &c); //[3 3 1 1] // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000","breadcrumbs":"Write to single Array using Channel","id":"60","title":"Write to single Array using Channel"},"7":{"body":"Google Groups ArrayFire Services: Consulting | Support | Training ArrayFire Blogs Email: mailto:technical@arrayfire.com","breadcrumbs":"Where to go for help?","id":"7","title":"Where to go for help?"},"8":{"body":"Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is necessary to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be immediately intuitive. ArrayFire provides many ways to vectorize a given code segment. In this chapter, we present several methods to vectorize code using ArrayFire and discuss the benefits and drawbacks associated with each method.","breadcrumbs":"Vectorization","id":"8","title":"Vectorization"},"9":{"body":"By its very nature, ArrayFire is a vectorized library. Most functions operate on Arrays as a whole i.e. on all elements in parallel. For example consider the following code: let mut a = af::range(Dim::new(&[10, 1, 1, 1])); // [0, 9]\na = a + 1; // [1, 10] This code will result in a single kernel that operates on all 10 elements of a in parallel. A small subset of such vectorized ArrayFire functions are given below for quick reference: Operator Category Functions Arithmetic operations +, -, *, /, %, >>, << Logical operations &&, ||, <, >, ==, != etc. Numeric functions abs , floor , round , min , max , etc. Complex operations real , imag , conjg , etc. Exponential and logarithmic fns exp , log , expm1 , log1p , etc. Trigonometric functions sin , cos , tan , etc. Hyperbolic functions sinh , cosh , tanh , etc. In addition to element-wise operations, many other functions are also vectorized in ArrayFire. Notice that even functions that perform some form of aggregation (e.g. sum or min ), signal processing (like convolve ), and image processing functions (i.e. rotate etc.) all support vectorization on different columns or images. For example, if we have NUM images of size WIDTHxHEIGHT, one could convolve each image in a vector fashion as follows: let g_coef: [f32, 9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; let f = Array::new(g_coef, Dim4::new(&[3, 3, 1, 1]));\nlet filter = f * 1.0f32/16; let signal = randu(WIDTH, HEIGHT, NUM);\nlet conv = convolve2(signal, filter, ConvMode::DEFAULT, ConvDomain::AUTO); Similarly, one can rotate 100 images by 45 degrees in a single call using code like the following: // Construct an array of 100 WIDTH x HEIGHT images of random numbers\nlet imgs = randu(WIDTH, HEIGHT, 100); // Rotate all of the images in a single command\nlet rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR); Although most functions in ArrayFire do support vectorization, some do not. Most notably, all linear algebra functions. Even though they are not vectorized linear algebra operations, they still execute in parallel on your hardware. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with ArrayFire.","breadcrumbs":"Generic/Default vectorization","id":"9","title":"Generic/Default vectorization"}},"length":61,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"0":{"0":{"0":{"0":{"df":3,"docs":{"18":{"tf":3.872983346207417},"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"7":{"8":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"7":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"2":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"2":{"2":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"1":{"5":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"2":{"8":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"8":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"1":{"2":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"9":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"9":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"5":{"7":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"6":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"4":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"3":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"1":{"2":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"9":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"6":{"5":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"7":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"1":{"6":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"4":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"2":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"2":{"8":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"3":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"9":{"7":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"6":{"7":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"1":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"0":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"5":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"8":{"8":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"8":{"9":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"9":{"3":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"8":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"5":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"0":{"9":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"5":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"9":{"6":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"6":{"2":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"1":{"0":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"5":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"7":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"7":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"0":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"21":{"tf":2.449489742783178},"27":{"tf":1.0},"28":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}},"1":{".":{"0":{"0":{"0":{"0":{"df":8,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"2":{"tf":1.4142135623730951},"25":{"tf":3.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"/":{"1":{"6":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"0":{".":{"0":{"0":{"0":{"0":{"df":1,"docs":{"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"0":{"df":1,"docs":{"44":{"tf":1.0}}},"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"6":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}},":":{"1":{":":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":30,"docs":{"1":{"tf":3.1622776601683795},"13":{"tf":3.605551275463989},"14":{"tf":2.23606797749979},"15":{"tf":2.6457513110645907},"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"19":{"tf":3.1622776601683795},"2":{"tf":2.449489742783178},"20":{"tf":2.0},"21":{"tf":4.0},"24":{"tf":3.0},"27":{"tf":4.0},"28":{"tf":3.605551275463989},"29":{"tf":3.1622776601683795},"3":{"tf":1.4142135623730951},"30":{"tf":4.242640687119285},"33":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"59":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}},"u":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"0":{"0":{"0":{"df":9,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178},"28":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":4.58257569495584},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"0":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"d":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}},"df":13,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":2.8284271247461903},"18":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"21":{"tf":2.6457513110645907},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"9":{"tf":2.0}},"n":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"x":{"4":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"3":{".":{"0":{"0":{"0":{"0":{"df":7,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}},"4":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"2":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0}}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":21,"docs":{"1":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"19":{"tf":2.0},"2":{"tf":1.4142135623730951},"20":{"tf":2.0},"21":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":2.6457513110645907},"28":{"tf":2.8284271247461903},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"54":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":2.23606797749979},"6":{"tf":1.0},"60":{"tf":2.23606797749979},"9":{"tf":1.0}},"r":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"4":{".":{"0":{"0":{"0":{"0":{"df":5,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{".":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"9":{"tf":1.0}}},"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"df":1,"docs":{"45":{"tf":1.0}}},"df":11,"docs":{"1":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"24":{"tf":2.449489742783178},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":2.23606797749979},"3":{"tf":1.0},"30":{"tf":3.1622776601683795}},"x":{"2":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}},"6":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"7":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"59":{"tf":3.0},"60":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"55":{"tf":1.0}},"x":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"9":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"_":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"c":{"df":3,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951},"58":{"tf":2.0}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"i":{"df":1,"docs":{"60":{"tf":1.0}}},"o":{"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":1,"docs":{"24":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"a":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"k":{".":{"a":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"b":{"df":1,"docs":{"9":{"tf":1.0}},"o":{"df":0,"docs":{},"v":{"df":7,"docs":{"1":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"c":{"c":{"df":2,"docs":{"36":{"tf":1.0},"37":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"2":{"tf":1.0},"25":{"tf":1.0},"5":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"59":{"tf":1.7320508075688772},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"49":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"d":{"d":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"_":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":7,"docs":{"32":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":4,"docs":{"10":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.0},"55":{"tf":1.4142135623730951}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{":":{":":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"f":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"50":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"a":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"\\":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"\\":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":2,"docs":{"54":{"tf":1.7320508075688772},"55":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"=":{"1":{"df":1,"docs":{"43":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"43":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"=":{"0":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"35":{"tf":1.0},"36":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"35":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.0}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"36":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.0}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"1":{",":{"3":{",":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"24":{"tf":1.0}}},"c":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}},"s":{"=":{"1":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"l":{":":{":":{"a":{"d":{"d":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"l":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"r":{"a":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"o":{"c":{"df":3,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":6,"docs":{"12":{"tf":1.7320508075688772},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"24":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"n":{"d":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"11":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"'":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":8,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":2.0},"56":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"24":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}}},"r":{"c":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"(":{"&":{"1":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"a":{"df":0,"docs":{},"y":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"50":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"x":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"y":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":36,"docs":{"0":{"tf":2.449489742783178},"1":{"tf":3.4641016151377544},"12":{"tf":2.8284271247461903},"13":{"tf":2.0},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"2":{"tf":3.0},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.1622776601683795},"24":{"tf":1.4142135623730951},"25":{"tf":2.23606797749979},"26":{"tf":1.0},"27":{"tf":2.0},"28":{"tf":2.0},"29":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":2.23606797749979},"53":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.7320508075688772},"56":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.7320508075688772},"59":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":29,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":2.0},"10":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":2.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"38":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":2.6457513110645907},"50":{"tf":3.4641016151377544},"51":{"tf":4.47213595499958},"52":{"tf":2.0},"53":{"tf":3.0},"54":{"tf":3.872983346207417},"55":{"tf":4.0},"56":{"tf":1.4142135623730951},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":2.23606797749979}},"e":{"'":{"df":8,"docs":{"3":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":3.1622776601683795},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"28":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"13":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"53":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"d":{"df":4,"docs":{"25":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}},"x":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0}}}}},"b":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"13":{"tf":1.0},"54":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"53":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"22":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}},"i":{"c":{"df":3,"docs":{"0":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":8,"docs":{"21":{"tf":1.0},"25":{"tf":2.0},"28":{"tf":2.0},"3":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979},"60":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"40":{"tf":1.0},"50":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"44":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":11,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"25":{"tf":1.4142135623730951},"30":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"a":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":2,"docs":{"0":{"tf":3.0},"1":{"tf":1.0}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"h":{"df":4,"docs":{"19":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"0":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"18":{"tf":1.0},"38":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"58":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"c":{"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":9,"docs":{"3":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"50":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":2.0},"50":{"tf":1.0},"51":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":1.0},"60":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"29":{"tf":1.0},"38":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.4142135623730951}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"56":{"tf":1.0},"8":{"tf":1.0}}}}}},"r":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":4,"docs":{"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"37":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"36":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}},"i":{"d":{"df":1,"docs":{"53":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"53":{"tf":1.7320508075688772},"54":{"tf":2.0},"55":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"b":{"df":0,"docs":{},"j":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":15,"docs":{"21":{"tf":1.4142135623730951},"24":{"tf":1.0},"3":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":2.0}}}},"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"l":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"44":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"21":{"tf":1.7320508075688772},"22":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"3":{"tf":1.0},"39":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"x":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"21":{"tf":1.0},"9":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"0":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}},"n":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{".":{"0":{"df":1,"docs":{"25":{"tf":1.0}},"f":{"3":{"2":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}},"f":{"3":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":4,"docs":{"1":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}},"df":2,"docs":{"1":{"tf":1.7320508075688772},"25":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"2":{"tf":1.0},"7":{"tf":1.0}}}},"m":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0}}}},"x":{"df":0,"docs":{},"t":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},":":{":":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":7,"docs":{"50":{"tf":2.0},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"_":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":6,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"v":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{":":{":":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"3":{"tf":1.0}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"2":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":6,"docs":{"22":{"tf":1.0},"38":{"tf":1.0},"5":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":5,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":15,"docs":{"0":{"tf":1.0},"1":{"tf":2.23606797749979},"22":{"tf":1.7320508075688772},"24":{"tf":1.0},"27":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"1":{"tf":1.0},"40":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"\"":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"!":{"(":{"\"":{".":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"a":{"d":{"d":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"\"":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"r":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"u":{"d":{"a":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"34":{"tf":1.0},"46":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":1.7320508075688772},"50":{"tf":3.0},"51":{"tf":2.6457513110645907},"52":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"/":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.4142135623730951},"53":{"tf":2.449489742783178},"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":7,"docs":{"48":{"tf":1.7320508075688772},"49":{"tf":1.0},"50":{"tf":2.0},"52":{"tf":1.7320508075688772},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}}}}},"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"a":{"df":0,"docs":{},"t":{"a":{"df":10,"docs":{"0":{"tf":2.0},"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":4,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":12,"docs":{"1":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"58":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"0":{"tf":1.0},"33":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"2":{"tf":2.23606797749979}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"c":{"df":23,"docs":{"0":{"tf":1.0},"1":{"tf":2.0},"34":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"36":{"tf":1.7320508075688772},"37":{"tf":2.449489742783178},"38":{"tf":2.0},"4":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":3.0},"5":{"tf":1.0},"50":{"tf":2.0},"51":{"tf":2.449489742783178},"52":{"tf":1.0},"53":{"tf":3.605551275463989},"54":{"tf":1.7320508075688772},"55":{"tf":2.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"(":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":2.0}},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"51":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"[":{"1":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"12":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"51":{"tf":2.0}}},"df":0,"docs":{}},"3":{"df":6,"docs":{"25":{"tf":1.0},"28":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}},"5":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"df":2,"docs":{"19":{"tf":1.0},"21":{"tf":1.0}}},"2":{"df":1,"docs":{"13":{"tf":1.0}}},"3":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{"df":3,"docs":{"1":{"tf":1.4142135623730951},"24":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"2":{"tf":1.4142135623730951},"51":{"tf":1.0}}},"df":7,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":12,"docs":{"12":{"tf":2.449489742783178},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"2":{"tf":2.23606797749979},"20":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"4":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"s":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}},"[":{"0":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"54":{"tf":1.0}}},"2":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"38":{"tf":1.7320508075688772},"40":{"tf":1.7320508075688772},"43":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"40":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"v":{"df":1,"docs":{"58":{"tf":1.0}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}},"df":1,"docs":{"25":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":2.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"w":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":4,"docs":{"15":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"21":{"tf":1.0},"22":{"tf":1.0},"57":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951}}}}}}},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}},"i":{"df":2,"docs":{"0":{"tf":1.0},"22":{"tf":1.0}}}}},"df":3,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"30":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"58":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":8,"docs":{"31":{"tf":1.4142135623730951},"38":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"q":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"17":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"(":{"df":2,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"39":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"t":{"c":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"v":{"a":{"df":0,"docs":{},"l":{"!":{"(":{"a":{"[":{"1":{":":{"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"51":{"tf":1.0}},"u":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.4142135623730951}},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"33":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":23,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"25":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"4":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"29":{"tf":1.0},"33":{"tf":1.0},"54":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"4":{"tf":1.0},"41":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":15,"docs":{"22":{"tf":2.449489742783178},"24":{"tf":1.0},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"44":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.7320508075688772}}}},"t":{"df":1,"docs":{"55":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"m":{"1":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"2":{"tf":1.0},"3":{"tf":1.7320508075688772}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.4142135623730951}}}},"df":1,"docs":{"50":{"tf":1.0}},"n":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":2.0},"50":{"tf":2.449489742783178},"51":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"40":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"33":{"tf":1.0},"39":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"s":{"df":4,"docs":{"20":{"tf":1.0},"21":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"18":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}}},"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"30":{"tf":1.0},"49":{"tf":1.0},"54":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":2,"docs":{"21":{"tf":1.0},"3":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{",":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":6,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772},"36":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"a":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":2,"docs":{"14":{"tf":1.0},"21":{"tf":1.0}}},"b":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.4142135623730951}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"(":{"a":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.4142135623730951},"15":{"tf":2.0}}}},"o":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"n":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":10,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.4142135623730951},"55":{"tf":1.0},"56":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"c":{"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"g":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":2,"docs":{"1":{"tf":1.0},"43":{"tf":1.0}}},"df":2,"docs":{"44":{"tf":1.0},"51":{"tf":2.23606797749979}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"42":{"tf":1.0}},"i":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":35,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"2":{"tf":2.0},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":2.23606797749979},"38":{"tf":2.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.4142135623730951},"49":{"tf":1.4142135623730951},"5":{"tf":1.0},"51":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951},"53":{"tf":1.7320508075688772},"54":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"59":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"r":{"b":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"0":{"tf":1.4142135623730951},"2":{"tf":1.0},"21":{"tf":1.0},"27":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"54":{"tf":1.0}},"n":{"df":6,"docs":{"30":{"tf":1.4142135623730951},"49":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"o":{"df":7,"docs":{"43":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"7":{"tf":1.0}},"e":{"df":2,"docs":{"1":{"tf":1.0},"21":{"tf":1.0}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"57":{"tf":1.0}},"e":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"57":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"d":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"p":{"df":5,"docs":{"24":{"tf":1.0},"27":{"tf":1.4142135623730951},"31":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"0":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"d":{"df":2,"docs":{"57":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"1":{"tf":1.0},"38":{"tf":1.7320508075688772},"5":{"tf":2.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}}}}},"i":{".":{"df":2,"docs":{"15":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":6,"docs":{"48":{"tf":1.0},"49":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"57":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"35":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"r":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"s":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"32":{"tf":1.0},"38":{"tf":1.0}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":5,"docs":{"22":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":2.8284271247461903}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}}}}},"i":{"c":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}}}},"n":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.0},"2":{"tf":1.4142135623730951},"32":{"tf":1.4142135623730951},"49":{"tf":1.0},"53":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"a":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"a":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":6,"docs":{"22":{"tf":2.0},"24":{"tf":1.4142135623730951},"27":{"tf":1.7320508075688772},"28":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"i":{"c":{"df":6,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"25":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"o":{"df":4,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"51":{"tf":1.4142135623730951},"57":{"tf":1.0}},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"21":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}},"t":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"df":0,"docs":{},"g":{"df":2,"docs":{"0":{"tf":2.449489742783178},"6":{"tf":1.0}},"r":{"df":3,"docs":{"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"f":{"a":{"c":{"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"n":{"df":4,"docs":{"53":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}}},"o":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":4,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"a":{":":{":":{"<":{"df":0,"docs":{},"u":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"3":{"tf":2.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{"0":{"df":1,"docs":{"16":{"tf":1.0}}},"1":{"df":2,"docs":{"16":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":5,"docs":{"12":{"tf":1.4142135623730951},"16":{"tf":2.0},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":8,"docs":{"3":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"48":{"tf":1.0},"50":{"tf":3.0},"51":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":3.605551275463989},"9":{"tf":1.0}}}}}},"y":{"df":1,"docs":{"22":{"tf":1.0}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"!":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"<":{"<":{"<":{"1":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"54":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"t":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}}}}},"i":{"b":{"df":1,"docs":{"32":{"tf":1.0}},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"17":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"21":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"o":{"a":{"d":{"df":3,"docs":{"42":{"tf":1.7320508075688772},"50":{"tf":1.0},"54":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"33":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"g":{"1":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"51":{"tf":1.0}}}},"o":{"df":0,"docs":{},"k":{"df":3,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"56":{"tf":1.0}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}},"w":{"df":1,"docs":{"0":{"tf":1.0}}}}},"m":{"a":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":4,"docs":{"22":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"l":{"@":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"n":{"df":8,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"e":{"df":3,"docs":{"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":10,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"df":0,"docs":{},"i":{"df":5,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"12":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}}},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":6,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979},"54":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"x":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}},"x":{"df":1,"docs":{"9":{"tf":1.0}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":4,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":1,"docs":{"50":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"3":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":13,"docs":{"1":{"tf":2.449489742783178},"3":{"tf":1.0},"38":{"tf":1.7320508075688772},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":2.0},"5":{"tf":1.7320508075688772},"50":{"tf":1.4142135623730951},"51":{"tf":3.1622776601683795},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.23606797749979},"55":{"tf":3.0}}},"y":{":":{":":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{":":{":":{"<":{"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"1":{"0":{"*":{"1":{"0":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":8,"docs":{"12":{"tf":1.0},"2":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"x":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"k":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772}},"s":{"(":{"&":{"a":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}},"i":{"df":8,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"25":{"tf":1.0},"28":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":6,"docs":{"22":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.4142135623730951},"33":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"56":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"0":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"58":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"56":{"tf":1.0}},"p":{"df":0,"docs":{},"l":{"df":4,"docs":{"3":{"tf":1.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}},"t":{"df":10,"docs":{"25":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"50":{"tf":2.449489742783178},"51":{"tf":2.23606797749979},"55":{"tf":2.0},"57":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":6,"docs":{"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"43":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":1,"docs":{"21":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":13,"docs":{"0":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"g":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"w":{"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.4142135623730951}},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},":":{":":{"<":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":6,"docs":{"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":10,"docs":{"13":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"58":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":2,"docs":{"50":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"o":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":13,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.6457513110645907},"60":{"tf":2.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}}},"c":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{":":{":":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"&":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"_":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"{":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"v":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"k":{"(":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"m":{"df":1,"docs":{"50":{"tf":1.0}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":3,"docs":{"10":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":9,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.4142135623730951}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"u":{"b":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}},"df":3,"docs":{"58":{"tf":2.23606797749979},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":10,"docs":{"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":2.0},"39":{"tf":1.4142135623730951},"45":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.7320508075688772},"53":{"tf":1.7320508075688772},"54":{"tf":2.449489742783178},"55":{"tf":2.23606797749979}}}},"df":0,"docs":{}},"r":{"df":13,"docs":{"0":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"3":{"tf":2.449489742783178},"50":{"tf":1.0},"51":{"tf":2.0},"54":{"tf":2.449489742783178},"55":{"tf":2.0},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":3.0}}}},"s":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"30":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"x":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"1":{"tf":1.0},"38":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":2.449489742783178},"55":{"tf":1.0},"8":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"56":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"c":{"!":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":2.0},"51":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":5,"docs":{"0":{"tf":2.0},"4":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"42":{"tf":2.449489742783178}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"11":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":11,"docs":{"0":{"tf":1.4142135623730951},"12":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0},"25":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":4,"docs":{"4":{"tf":1.0},"44":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"49":{"tf":1.7320508075688772},"50":{"tf":1.0},"51":{"tf":2.8284271247461903},"53":{"tf":2.449489742783178}}}}}}},"p":{"df":1,"docs":{"55":{"tf":1.0}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":2.0},"21":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"53":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"50":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"d":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"0":{"tf":2.449489742783178}}}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":6,"docs":{"1":{"tf":1.0},"25":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"57":{"tf":1.0},"6":{"tf":1.0}}},"b":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"c":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"1":{"tf":1.0},"2":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"2":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"57":{"tf":1.0}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"\\":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}},"a":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"54":{"tf":1.7320508075688772},"56":{"tf":1.0}},"m":{"df":2,"docs":{"53":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.0},"3":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":3.1622776601683795},"55":{"tf":2.0}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"9":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"1":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"u":{"(":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},":":{":":{"<":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"2":{"df":1,"docs":{"25":{"tf":1.0}}},"5":{"df":5,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"5":{"df":1,"docs":{"27":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.4142135623730951},"3":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"w":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":1,"docs":{"54":{"tf":1.0}},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}},"d":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":4,"docs":{"55":{"tf":1.0},"56":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"22":{"tf":1.4142135623730951},"30":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0},"9":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.4142135623730951},"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"37":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":3,"docs":{"49":{"tf":1.0},"53":{"tf":1.7320508075688772},"55":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"&":{"a":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"57":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"55":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":6,"docs":{"5":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.0},"53":{"tf":1.4142135623730951},"54":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"30":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{")":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"(":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"2":{"tf":1.0},"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.7320508075688772},"4":{"tf":1.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"31":{"tf":1.0},"40":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"'":{"df":1,"docs":{"50":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"51":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"'":{"df":1,"docs":{"59":{"tf":1.0}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"x":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":1,"docs":{"60":{"tf":1.0}}}},"s":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":9,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"29":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}},"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":4,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":4,"docs":{"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"22":{"tf":1.7320508075688772},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"g":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"!":{"(":{"0":{":":{"2":{":":{"1":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{":":{"3":{":":{"1":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772}}}}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"0":{".":{"0":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"df":0,"docs":{},"u":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"24":{"tf":1.7320508075688772},"25":{"tf":1.7320508075688772},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":3,"docs":{"24":{"tf":1.4142135623730951},"27":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"40":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"57":{"tf":1.0}},"e":{"(":{"0":{"df":5,"docs":{"51":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"df":23,"docs":{"22":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.7320508075688772},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"df":10,"docs":{"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.4142135623730951},"21":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":4,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"12":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"6":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"w":{"c":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":4,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"42":{"tf":1.0}},"n":{"df":4,"docs":{"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"0":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"27":{"tf":1.0},"5":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"58":{"tf":1.0}}},"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.7320508075688772},"4":{"tf":1.0},"56":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.7320508075688772}}}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"z":{"df":0,"docs":{},"e":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"21":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":4,"docs":{"16":{"tf":1.0},"29":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}},"i":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"19":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.0}}}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"r":{"c":{"_":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":4,"docs":{"20":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"y":{"df":1,"docs":{"51":{"tf":1.0}}}},"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{":":{":":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{":":{":":{"a":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"48":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":3.872983346207417},"51":{"tf":2.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"50":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"u":{"b":{"df":5,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"58":{"tf":1.0}},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":3,"docs":{"22":{"tf":1.0},"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"h":{"df":8,"docs":{"1":{"tf":1.0},"38":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"m":{"df":1,"docs":{"9":{"tf":1.0}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":7,"docs":{"0":{"tf":1.7320508075688772},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"40":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"49":{"tf":1.4142135623730951},"53":{"tf":1.0},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"0":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"3":{"tf":1.0},"41":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":3,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.4142135623730951}}}}}}}},"t":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"n":{"df":1,"docs":{"9":{"tf":1.0}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"24":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"25":{"tf":1.0}}}}}}},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"40":{"tf":1.0},"42":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{":":{":":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{")":{".":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"d":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"1":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":4,"docs":{"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"56":{"tf":2.23606797749979},"57":{"tf":2.8284271247461903},"58":{"tf":2.449489742783178},"59":{"tf":3.3166247903554},"60":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"u":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"&":{"a":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"a":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"19":{"tf":1.0},"3":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"o":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}},"t":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.0},"20":{"tf":2.0}},"e":{"(":{"&":{"a":{"df":2,"docs":{"20":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"v":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"38":{"tf":1.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"o":{"df":2,"docs":{"24":{"tf":1.0},"53":{"tf":1.0}}}},"x":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"60":{"tf":1.0}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":7,"docs":{"0":{"tf":2.0},"1":{"tf":2.0},"2":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"u":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":3,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"38":{"tf":1.0},"42":{"tf":1.0}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"1":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"s":{"a":{"df":0,"docs":{},"f":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":2.449489742783178},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":2.6457513110645907}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":5,"docs":{"12":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"s":{"df":42,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"16":{"tf":1.4142135623730951},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.0},"23":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":3.1622776601683795},"51":{"tf":3.0},"53":{"tf":1.4142135623730951},"54":{"tf":3.7416573867739413},"55":{"tf":3.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"i":{"df":0,"docs":{},"z":{"df":2,"docs":{"54":{"tf":2.0},"60":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"3":{".":{"4":{"df":4,"docs":{"38":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":6,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"51":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":18,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":2.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":15,"docs":{"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":1.7320508075688772},"36":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"2":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"!":{"[":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"<":{"_":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"55":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.1622776601683795}}}}}},"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":4,"docs":{"38":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"!":{"(":{"a":{"[":{"1":{":":{"3":{":":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"27":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"25":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}},"y":{"df":2,"docs":{"25":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}},"x":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}}},"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"48":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"3":{"tf":1.0},"40":{"tf":1.0}}}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":7,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":8,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"56":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"x":{",":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}},".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979},"9":{"tf":1.0}}},"y":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"43":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772}}}}}}}}}},"breadcrumbs":{"root":{"0":{".":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"0":{"0":{"0":{"0":{"df":3,"docs":{"18":{"tf":3.872983346207417},"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"7":{"8":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"7":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"2":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"2":{"2":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"1":{"5":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"2":{"8":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"8":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"1":{"2":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"9":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"9":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"5":{"7":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"6":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"4":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"3":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"1":{"2":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"9":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"6":{"5":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"7":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"1":{"6":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"4":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"2":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"2":{"8":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"3":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"9":{"7":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"6":{"7":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"1":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"0":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"5":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"8":{"8":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"8":{"9":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"9":{"3":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"8":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"5":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"0":{"9":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"5":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"9":{"6":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"6":{"2":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"1":{"0":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"5":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"7":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"7":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"0":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"21":{"tf":2.449489742783178},"27":{"tf":1.0},"28":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}},"1":{".":{"0":{"0":{"0":{"0":{"df":8,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"2":{"tf":1.4142135623730951},"25":{"tf":3.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"/":{"1":{"6":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"0":{".":{"0":{"0":{"0":{"0":{"df":1,"docs":{"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"0":{"df":1,"docs":{"44":{"tf":1.0}}},"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"6":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}},":":{"1":{":":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":30,"docs":{"1":{"tf":3.1622776601683795},"13":{"tf":3.605551275463989},"14":{"tf":2.23606797749979},"15":{"tf":2.6457513110645907},"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"19":{"tf":3.1622776601683795},"2":{"tf":2.449489742783178},"20":{"tf":2.0},"21":{"tf":4.0},"24":{"tf":3.0},"27":{"tf":4.0},"28":{"tf":3.605551275463989},"29":{"tf":3.1622776601683795},"3":{"tf":1.4142135623730951},"30":{"tf":4.242640687119285},"33":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"59":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}},"u":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"0":{"0":{"0":{"df":9,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178},"28":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":4.58257569495584},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"0":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"d":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}},"df":13,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":2.8284271247461903},"18":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"21":{"tf":2.6457513110645907},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"9":{"tf":2.0}},"n":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"x":{"4":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"3":{".":{"0":{"0":{"0":{"0":{"df":7,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}},"4":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"2":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0}}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":21,"docs":{"1":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"19":{"tf":2.0},"2":{"tf":1.4142135623730951},"20":{"tf":2.0},"21":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":2.6457513110645907},"28":{"tf":2.8284271247461903},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"54":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":2.23606797749979},"6":{"tf":1.0},"60":{"tf":2.23606797749979},"9":{"tf":1.0}},"r":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"4":{".":{"0":{"0":{"0":{"0":{"df":5,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{".":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"9":{"tf":1.0}}},"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"df":1,"docs":{"45":{"tf":1.0}}},"df":11,"docs":{"1":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"24":{"tf":2.449489742783178},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":2.23606797749979},"3":{"tf":1.0},"30":{"tf":3.1622776601683795}},"x":{"2":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}},"6":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"7":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"59":{"tf":3.0},"60":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"55":{"tf":1.0}},"x":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"9":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"_":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"c":{"df":3,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951},"58":{"tf":2.0}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"i":{"df":1,"docs":{"60":{"tf":1.0}}},"o":{"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":1,"docs":{"24":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"a":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"k":{".":{"a":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"b":{"df":1,"docs":{"9":{"tf":1.0}},"o":{"df":0,"docs":{},"v":{"df":7,"docs":{"1":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"c":{"c":{"df":2,"docs":{"36":{"tf":1.0},"37":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"2":{"tf":1.0},"25":{"tf":1.0},"5":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"59":{"tf":1.7320508075688772},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"49":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"d":{"d":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"_":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":7,"docs":{"32":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":4,"docs":{"10":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{":":{":":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"f":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"50":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"a":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"\\":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"\\":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":2,"docs":{"54":{"tf":1.7320508075688772},"55":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.4142135623730951}},"e":{"=":{"1":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"=":{"1":{"df":1,"docs":{"43":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"43":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"=":{"0":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"35":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.4142135623730951}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"36":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.4142135623730951}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"1":{",":{"3":{",":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"24":{"tf":1.0}}},"c":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.4142135623730951}},"s":{"=":{"1":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"l":{":":{":":{"a":{"d":{"d":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"l":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"r":{"a":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"o":{"c":{"df":3,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":6,"docs":{"12":{"tf":1.7320508075688772},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"24":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"n":{"d":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"11":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"'":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":8,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"56":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"24":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}}},"r":{"c":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"(":{"&":{"1":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"a":{"df":0,"docs":{},"y":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"50":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"x":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"y":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":36,"docs":{"0":{"tf":2.449489742783178},"1":{"tf":3.605551275463989},"12":{"tf":3.0},"13":{"tf":2.0},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"2":{"tf":3.1622776601683795},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.1622776601683795},"24":{"tf":1.7320508075688772},"25":{"tf":2.449489742783178},"26":{"tf":1.4142135623730951},"27":{"tf":2.23606797749979},"28":{"tf":2.23606797749979},"29":{"tf":2.0},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":2.23606797749979},"53":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.7320508075688772},"56":{"tf":2.0},"57":{"tf":1.7320508075688772},"58":{"tf":2.0},"59":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"60":{"tf":2.0},"9":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":29,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":2.0},"10":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":2.23606797749979},"31":{"tf":1.7320508075688772},"32":{"tf":1.0},"38":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":2.6457513110645907},"50":{"tf":3.605551275463989},"51":{"tf":4.58257569495584},"52":{"tf":2.0},"53":{"tf":3.0},"54":{"tf":4.0},"55":{"tf":4.123105625617661},"56":{"tf":1.7320508075688772},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":2.23606797749979}},"e":{"'":{"df":8,"docs":{"3":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":3.1622776601683795},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"28":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"13":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"53":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"d":{"df":4,"docs":{"25":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}},"x":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0}}}}},"b":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"13":{"tf":1.0},"54":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"53":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"22":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}},"i":{"c":{"df":3,"docs":{"0":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":8,"docs":{"21":{"tf":1.0},"25":{"tf":2.0},"28":{"tf":2.0},"3":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979},"60":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"40":{"tf":1.0},"50":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"44":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":11,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"25":{"tf":1.4142135623730951},"30":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"a":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":2,"docs":{"0":{"tf":3.0},"1":{"tf":1.0}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.7320508075688772}}}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"h":{"df":4,"docs":{"19":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"0":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"18":{"tf":1.0},"38":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"58":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"c":{"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":9,"docs":{"3":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"50":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":2.0},"50":{"tf":1.0},"51":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":1.0},"60":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"29":{"tf":1.0},"38":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"56":{"tf":1.0},"8":{"tf":1.0}}}}}},"r":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":4,"docs":{"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"37":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"36":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}},"i":{"d":{"df":1,"docs":{"53":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"53":{"tf":1.7320508075688772},"54":{"tf":2.0},"55":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"b":{"df":0,"docs":{},"j":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":15,"docs":{"21":{"tf":1.4142135623730951},"24":{"tf":1.0},"3":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":2.0}}}},"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"l":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"44":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"21":{"tf":2.0},"22":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"3":{"tf":1.0},"39":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"x":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"21":{"tf":1.0},"9":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"0":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}},"n":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{".":{"0":{"df":1,"docs":{"25":{"tf":1.0}},"f":{"3":{"2":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}},"f":{"3":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":4,"docs":{"1":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}},"df":2,"docs":{"1":{"tf":1.7320508075688772},"25":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"2":{"tf":1.0},"7":{"tf":1.0}}}},"m":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0}}}},"x":{"df":0,"docs":{},"t":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},":":{":":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":7,"docs":{"50":{"tf":2.0},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"_":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":6,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"v":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{":":{":":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"3":{"tf":1.0}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"2":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":6,"docs":{"22":{"tf":1.0},"38":{"tf":1.0},"5":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":5,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":15,"docs":{"0":{"tf":1.0},"1":{"tf":2.449489742783178},"22":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"1":{"tf":1.0},"40":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"\"":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"!":{"(":{"\"":{".":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"a":{"d":{"d":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"\"":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"r":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"u":{"d":{"a":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"34":{"tf":1.0},"46":{"tf":1.0},"48":{"tf":2.23606797749979},"49":{"tf":1.7320508075688772},"50":{"tf":3.1622776601683795},"51":{"tf":2.8284271247461903},"52":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"/":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.4142135623730951},"53":{"tf":2.449489742783178},"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":7,"docs":{"48":{"tf":1.7320508075688772},"49":{"tf":1.0},"50":{"tf":2.23606797749979},"52":{"tf":1.7320508075688772},"53":{"tf":1.4142135623730951},"54":{"tf":2.23606797749979},"55":{"tf":1.0}}}}}}}},"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"a":{"df":0,"docs":{},"t":{"a":{"df":10,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":4,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":12,"docs":{"1":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"58":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"0":{"tf":1.0},"33":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"2":{"tf":2.23606797749979}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"c":{"df":23,"docs":{"0":{"tf":1.0},"1":{"tf":2.0},"34":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"36":{"tf":1.7320508075688772},"37":{"tf":2.449489742783178},"38":{"tf":2.0},"4":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":3.0},"5":{"tf":1.0},"50":{"tf":2.0},"51":{"tf":2.449489742783178},"52":{"tf":1.0},"53":{"tf":3.605551275463989},"54":{"tf":1.7320508075688772},"55":{"tf":2.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"(":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":2.0}},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"51":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"[":{"1":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"12":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"51":{"tf":2.0}}},"df":0,"docs":{}},"3":{"df":6,"docs":{"25":{"tf":1.0},"28":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}},"5":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"df":2,"docs":{"19":{"tf":1.0},"21":{"tf":1.0}}},"2":{"df":1,"docs":{"13":{"tf":1.0}}},"3":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{"df":3,"docs":{"1":{"tf":1.4142135623730951},"24":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"2":{"tf":1.4142135623730951},"51":{"tf":1.0}}},"df":7,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":12,"docs":{"12":{"tf":2.449489742783178},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"2":{"tf":2.23606797749979},"20":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"4":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"s":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}},"[":{"0":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"54":{"tf":1.0}}},"2":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"38":{"tf":1.7320508075688772},"40":{"tf":1.7320508075688772},"43":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"40":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"v":{"df":1,"docs":{"58":{"tf":1.0}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}},"df":1,"docs":{"25":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":2.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"w":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":4,"docs":{"15":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"21":{"tf":1.0},"22":{"tf":1.0},"57":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951}}}}}}},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}},"i":{"df":2,"docs":{"0":{"tf":1.0},"22":{"tf":1.0}}}}},"df":3,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"30":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"58":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":8,"docs":{"31":{"tf":1.7320508075688772},"38":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"q":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"17":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"(":{"df":2,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"39":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"t":{"c":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"v":{"a":{"df":0,"docs":{},"l":{"!":{"(":{"a":{"[":{"1":{":":{"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"51":{"tf":1.0}},"u":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.4142135623730951}},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"33":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":23,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"25":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"4":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"29":{"tf":1.0},"33":{"tf":1.0},"54":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"4":{"tf":1.0},"41":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":15,"docs":{"22":{"tf":2.449489742783178},"24":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"29":{"tf":1.0},"30":{"tf":1.0},"44":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.23606797749979},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"t":{"df":1,"docs":{"55":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"m":{"1":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"2":{"tf":1.0},"3":{"tf":2.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.7320508075688772}}}},"df":1,"docs":{"50":{"tf":1.0}},"n":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":2.0},"50":{"tf":2.449489742783178},"51":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"40":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"33":{"tf":1.0},"39":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"s":{"df":4,"docs":{"20":{"tf":1.0},"21":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"18":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}}},"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"30":{"tf":1.0},"49":{"tf":1.0},"54":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":2,"docs":{"21":{"tf":1.0},"3":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{",":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":6,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772},"36":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"a":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":2,"docs":{"14":{"tf":1.0},"21":{"tf":1.0}}},"b":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"(":{"a":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979}}}},"o":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"n":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":10,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.4142135623730951},"55":{"tf":1.0},"56":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"c":{"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"g":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":2,"docs":{"1":{"tf":1.0},"43":{"tf":1.0}}},"df":2,"docs":{"44":{"tf":1.0},"51":{"tf":2.23606797749979}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"42":{"tf":1.0}},"i":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":35,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"2":{"tf":2.0},"20":{"tf":1.0},"21":{"tf":2.0},"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":2.23606797749979},"38":{"tf":2.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.4142135623730951},"49":{"tf":1.4142135623730951},"5":{"tf":1.0},"51":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951},"53":{"tf":1.7320508075688772},"54":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"59":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"r":{"b":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"0":{"tf":1.4142135623730951},"2":{"tf":1.0},"21":{"tf":1.0},"27":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"54":{"tf":1.0}},"n":{"df":6,"docs":{"30":{"tf":1.4142135623730951},"49":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"o":{"df":7,"docs":{"43":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"7":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"1":{"tf":1.0},"21":{"tf":1.0}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"57":{"tf":1.0}},"e":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"57":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"d":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"p":{"df":5,"docs":{"24":{"tf":1.0},"27":{"tf":1.4142135623730951},"31":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.4142135623730951}}}},"n":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"0":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"d":{"df":2,"docs":{"57":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"1":{"tf":1.0},"38":{"tf":1.7320508075688772},"5":{"tf":2.23606797749979},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}}}}},"i":{".":{"df":2,"docs":{"15":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":6,"docs":{"48":{"tf":1.0},"49":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"57":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"35":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"r":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"s":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"32":{"tf":1.0},"38":{"tf":1.0}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":5,"docs":{"22":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":2.8284271247461903}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}}}}},"i":{"c":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}}}},"n":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.0},"2":{"tf":1.4142135623730951},"32":{"tf":1.4142135623730951},"49":{"tf":1.0},"53":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"a":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"a":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":6,"docs":{"22":{"tf":2.23606797749979},"24":{"tf":1.4142135623730951},"27":{"tf":1.7320508075688772},"28":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":2.23606797749979}},"e":{"df":0,"docs":{},"r":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"i":{"c":{"df":6,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"25":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"o":{"df":4,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"51":{"tf":1.4142135623730951},"57":{"tf":1.0}},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"21":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}},"t":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"df":0,"docs":{},"g":{"df":2,"docs":{"0":{"tf":2.449489742783178},"6":{"tf":1.0}},"r":{"df":3,"docs":{"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"f":{"a":{"c":{"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"n":{"df":4,"docs":{"53":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.7320508075688772},"52":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}}},"o":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":4,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"a":{":":{":":{"<":{"df":0,"docs":{},"u":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"3":{"tf":2.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{"0":{"df":1,"docs":{"16":{"tf":1.0}}},"1":{"df":2,"docs":{"16":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":5,"docs":{"12":{"tf":1.4142135623730951},"16":{"tf":2.23606797749979},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":8,"docs":{"3":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"48":{"tf":1.0},"50":{"tf":3.1622776601683795},"51":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":3.7416573867739413},"9":{"tf":1.0}}}}}},"y":{"df":1,"docs":{"22":{"tf":1.0}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"!":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"<":{"<":{"<":{"1":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"54":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"t":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}}}}},"i":{"b":{"df":1,"docs":{"32":{"tf":1.0}},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"17":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"21":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"o":{"a":{"d":{"df":3,"docs":{"42":{"tf":1.7320508075688772},"50":{"tf":1.0},"54":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"33":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"g":{"1":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"51":{"tf":1.0}}}},"o":{"df":0,"docs":{},"k":{"df":3,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"56":{"tf":1.0}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}},"w":{"df":1,"docs":{"0":{"tf":1.0}}}}},"m":{"a":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":4,"docs":{"22":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"l":{"@":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"n":{"df":8,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"e":{"df":3,"docs":{"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":10,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"df":0,"docs":{},"i":{"df":5,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"21":{"tf":1.0}}}}}}},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":6,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979},"54":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"x":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}},"x":{"df":1,"docs":{"9":{"tf":1.0}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":4,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":1,"docs":{"50":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"3":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":13,"docs":{"1":{"tf":2.449489742783178},"3":{"tf":1.0},"38":{"tf":1.7320508075688772},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":2.0},"5":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":3.1622776601683795},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.23606797749979},"55":{"tf":3.0}}},"y":{":":{":":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{":":{":":{"<":{"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"1":{"0":{"*":{"1":{"0":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":8,"docs":{"12":{"tf":1.0},"2":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"x":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"k":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":2.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}},"i":{"df":8,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":6,"docs":{"22":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.4142135623730951},"33":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"56":{"tf":1.0},"57":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"0":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"58":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"56":{"tf":1.0}},"p":{"df":0,"docs":{},"l":{"df":4,"docs":{"3":{"tf":1.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.7320508075688772},"59":{"tf":1.4142135623730951}}}}}}},"t":{"df":10,"docs":{"25":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"50":{"tf":2.449489742783178},"51":{"tf":2.23606797749979},"55":{"tf":2.0},"57":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":6,"docs":{"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"43":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":1,"docs":{"21":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":13,"docs":{"0":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"g":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":2.0}}},"w":{"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.4142135623730951}},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},":":{":":{"<":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":6,"docs":{"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":10,"docs":{"13":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"58":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":2,"docs":{"50":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"o":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":13,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.6457513110645907},"60":{"tf":2.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}}},"c":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{":":{":":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"&":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"_":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"{":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"v":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"k":{"(":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"m":{"df":1,"docs":{"50":{"tf":1.0}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":3,"docs":{"10":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":9,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.4142135623730951}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"u":{"b":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}},"df":3,"docs":{"58":{"tf":2.23606797749979},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":10,"docs":{"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":2.0},"39":{"tf":1.4142135623730951},"45":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":2.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.6457513110645907},"55":{"tf":2.449489742783178}}}},"df":0,"docs":{}},"r":{"df":13,"docs":{"0":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"3":{"tf":2.449489742783178},"50":{"tf":1.0},"51":{"tf":2.0},"54":{"tf":2.449489742783178},"55":{"tf":2.0},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":2.0},"9":{"tf":3.0}}}},"s":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"30":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"x":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"1":{"tf":1.0},"38":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":2.449489742783178},"55":{"tf":1.0},"8":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"56":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"c":{"!":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":2.0},"51":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":5,"docs":{"0":{"tf":2.0},"4":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"42":{"tf":2.449489742783178}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"11":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":11,"docs":{"0":{"tf":1.4142135623730951},"12":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0},"25":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":4,"docs":{"4":{"tf":1.0},"44":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"49":{"tf":1.7320508075688772},"50":{"tf":1.0},"51":{"tf":2.8284271247461903},"53":{"tf":2.449489742783178}}}}}}},"p":{"df":1,"docs":{"55":{"tf":1.0}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":2.23606797749979},"21":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"53":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"50":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"d":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"0":{"tf":2.449489742783178}}}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":6,"docs":{"1":{"tf":1.0},"25":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"57":{"tf":1.0},"6":{"tf":1.0}}},"b":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"c":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"1":{"tf":1.0},"2":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"2":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"57":{"tf":1.0}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"\\":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}},"a":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"54":{"tf":1.7320508075688772},"56":{"tf":1.0}},"m":{"df":2,"docs":{"53":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.0},"3":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":3.1622776601683795},"55":{"tf":2.0}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"9":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"1":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"u":{"(":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},":":{":":{"<":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"2":{"df":1,"docs":{"25":{"tf":1.0}}},"5":{"df":5,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"5":{"df":1,"docs":{"27":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.4142135623730951},"3":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"w":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":1,"docs":{"54":{"tf":1.0}},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}},"d":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":4,"docs":{"55":{"tf":1.0},"56":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0}}},"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"22":{"tf":1.4142135623730951},"30":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0},"9":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"37":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":3,"docs":{"49":{"tf":1.0},"53":{"tf":1.7320508075688772},"55":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"&":{"a":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"57":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"55":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":6,"docs":{"5":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.0},"53":{"tf":1.4142135623730951},"54":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"30":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{")":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"(":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"2":{"tf":1.0},"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.7320508075688772},"4":{"tf":1.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"31":{"tf":1.0},"40":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"'":{"df":1,"docs":{"50":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"51":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"'":{"df":1,"docs":{"59":{"tf":1.0}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"x":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":1,"docs":{"60":{"tf":1.0}}}},"s":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":9,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"29":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}},"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":4,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":4,"docs":{"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"22":{"tf":1.7320508075688772},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"g":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"!":{"(":{"0":{":":{"2":{":":{"1":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{":":{"3":{":":{"1":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772}}}}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"0":{".":{"0":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"df":0,"docs":{},"u":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"25":{"tf":1.7320508075688772},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":3,"docs":{"24":{"tf":1.4142135623730951},"27":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"40":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"57":{"tf":1.0}},"e":{"(":{"0":{"df":5,"docs":{"51":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"df":23,"docs":{"22":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":2.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"df":10,"docs":{"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.4142135623730951},"21":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":4,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"12":{"tf":1.4142135623730951},"18":{"tf":2.0},"6":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"w":{"c":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":4,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"42":{"tf":1.0}},"n":{"df":4,"docs":{"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"0":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"27":{"tf":1.0},"5":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"58":{"tf":1.0}}},"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.7320508075688772},"4":{"tf":1.0},"56":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"z":{"df":0,"docs":{},"e":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"21":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":4,"docs":{"16":{"tf":1.0},"29":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}},"i":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"19":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.0}}}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"r":{"c":{"_":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":4,"docs":{"20":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"y":{"df":1,"docs":{"51":{"tf":1.0}}}},"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{":":{":":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{":":{":":{"a":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"48":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":3.872983346207417},"51":{"tf":2.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"50":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"u":{"b":{"df":5,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"58":{"tf":1.0}},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":3,"docs":{"22":{"tf":1.0},"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"h":{"df":8,"docs":{"1":{"tf":1.0},"38":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"m":{"df":1,"docs":{"9":{"tf":1.0}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":7,"docs":{"0":{"tf":2.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"40":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"49":{"tf":1.4142135623730951},"53":{"tf":1.0},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"0":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"3":{"tf":1.0},"41":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":3,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.4142135623730951}}}}}}}},"t":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"n":{"df":1,"docs":{"9":{"tf":1.0}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"24":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"25":{"tf":1.0}}}}}}},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"40":{"tf":1.0},"42":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{":":{":":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{")":{".":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"d":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"1":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":4,"docs":{"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"56":{"tf":2.449489742783178},"57":{"tf":3.0},"58":{"tf":2.6457513110645907},"59":{"tf":3.4641016151377544},"60":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"u":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"&":{"a":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"a":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"19":{"tf":1.0},"3":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"o":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}},"t":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.0},"20":{"tf":2.23606797749979}},"e":{"(":{"&":{"a":{"df":2,"docs":{"20":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"v":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"38":{"tf":1.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"o":{"df":2,"docs":{"24":{"tf":1.0},"53":{"tf":1.0}}}},"x":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"60":{"tf":1.0}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":7,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":2.0},"2":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"u":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":3,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"38":{"tf":1.0},"42":{"tf":1.0}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"1":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"s":{"a":{"df":0,"docs":{},"f":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":2.449489742783178},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":2.6457513110645907}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":5,"docs":{"12":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"s":{"df":42,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"16":{"tf":1.4142135623730951},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.0},"23":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":3.3166247903554},"51":{"tf":3.0},"53":{"tf":1.4142135623730951},"54":{"tf":3.7416573867739413},"55":{"tf":3.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"i":{"df":0,"docs":{},"z":{"df":2,"docs":{"54":{"tf":2.0},"60":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"3":{".":{"4":{"df":4,"docs":{"38":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":6,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"51":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":18,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":2.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":15,"docs":{"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":1.7320508075688772},"36":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"2":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"!":{"[":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"<":{"_":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"55":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":2.449489742783178},"9":{"tf":3.3166247903554}}}}}},"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":4,"docs":{"38":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"!":{"(":{"a":{"[":{"1":{":":{"3":{":":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":2.0},"27":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"25":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}},"y":{"df":2,"docs":{"25":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}},"x":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}}},"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"48":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"3":{"tf":1.0},"40":{"tf":1.0}}}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":7,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":8,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"48":{"tf":1.0},"52":{"tf":1.0},"56":{"tf":1.4142135623730951},"59":{"tf":2.0},"60":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"x":{",":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}},".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979},"9":{"tf":1.0}}},"y":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"43":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772}}}}}}}}}},"title":{"root":{"a":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"df":0,"docs":{}},"d":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":14,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"5":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":7,"docs":{"3":{"tf":1.0},"31":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"b":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"21":{"tf":1.0},"26":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"d":{"a":{"df":3,"docs":{"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"o":{"df":1,"docs":{"7":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":2,"docs":{"22":{"tf":1.0},"4":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}}}},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"12":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"57":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"30":{"tf":1.0}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":3,"docs":{"52":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":2,"docs":{"23":{"tf":1.0},"26":{"tf":1.0}}},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"u":{"b":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":4,"docs":{"56":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"60":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":2,"docs":{"24":{"tf":1.0},"27":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}}}}},"pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}}); \ No newline at end of file diff --git a/book/searchindex.json b/book/searchindex.json new file mode 100644 index 000000000..2521cccd8 --- /dev/null +++ b/book/searchindex.json @@ -0,0 +1 @@ +{"doc_urls":["getting_started.html#supported-data-types","getting_started.html#creating-and-populating-an-array","getting_started.html#properties-of-an-array","getting_started.html#writing-math-expressions-using-arrayfire","getting_started.html#indexing","getting_started.html#access-to-array-memory-on-the-host","getting_started.html#bitwise-operators","getting_started.html#where-to-go-for-help","vectorization.html#vectorization","vectorization.html#genericdefault-vectorization","vectorization.html#gfor","vectorization.html#batch_func","array_and_matrix_manipulation.html#array-and-matrix-manipulation","array_and_matrix_manipulation.html#moddims","array_and_matrix_manipulation.html#flat","array_and_matrix_manipulation.html#flip","array_and_matrix_manipulation.html#join","array_and_matrix_manipulation.html#reorder","array_and_matrix_manipulation.html#shift","array_and_matrix_manipulation.html#tile","array_and_matrix_manipulation.html#transpose","array_and_matrix_manipulation.html#combining-functions-to-enumerate-grid-coordinates","indexing.html#indexing","indexing.html#using-seq-objects","indexing.html#create-a-view-of-an-existing-array","indexing.html#modify-a-sub-region-of-an-existing-array","indexing.html#using-array-and-seq-combination","indexing.html#create-a-view-of-an-existing-array","indexing.html#modify-a-sub-region-of-an-existing-array","indexing.html#extract-or-set-rowscolumns-of-an-array","indexing.html#negative-indices","configuring_arrayfire_environment.html#configuring-arrayfire-environment","configuring_arrayfire_environment.html#af_path","configuring_arrayfire_environment.html#af_print_errors","configuring_arrayfire_environment.html#af_cuda_default_device","configuring_arrayfire_environment.html#af_opencl_default_device","configuring_arrayfire_environment.html#af_opencl_default_device_type","configuring_arrayfire_environment.html#af_opencl_device_type","configuring_arrayfire_environment.html#af_opencl_cpu_offload","configuring_arrayfire_environment.html#af_opencl_show_build_info","configuring_arrayfire_environment.html#af_disable_graphics","configuring_arrayfire_environment.html#af_synchronous_calls","configuring_arrayfire_environment.html#af_show_load_path","configuring_arrayfire_environment.html#af_mem_debug","configuring_arrayfire_environment.html#af_max_buffers","configuring_arrayfire_environment.html#af_opencl_max_jit_len","configuring_arrayfire_environment.html#af_cuda_max_jit_len","configuring_arrayfire_environment.html#af_cpu_max_jit_len","cuda-interop.html#interoperability-with-cuda","cuda-interop.html#basics","cuda-interop.html#using-custom-cuda-kernels-in-existing-arrayfire-application","cuda-interop.html#adding-arrayfire-to-existing-cuda-application","opencl-interop.html#interoperability-with-opencl","opencl-interop.html#basics","opencl-interop.html#adding-custom-opencl-kernels-to-an-existing-arrayfire-application","opencl-interop.html#adding-arrayfire-to-an-existing-opencl-application","multi-threading.html#arrayfire-in-threaded-applications","multi-threading.html#move-an-array-to-thread","multi-threading.html#read-array-from-multiple-threads","multi-threading.html#write-to-array-from-multiple-threads","multi-threading.html#write-to-single-array-using-channel"],"index":{"documentStore":{"docInfo":{"0":{"body":177,"breadcrumbs":3,"title":3},"1":{"body":153,"breadcrumbs":3,"title":3},"10":{"body":16,"breadcrumbs":1,"title":1},"11":{"body":7,"breadcrumbs":1,"title":1},"12":{"body":58,"breadcrumbs":3,"title":3},"13":{"body":76,"breadcrumbs":1,"title":1},"14":{"body":33,"breadcrumbs":1,"title":1},"15":{"body":69,"breadcrumbs":1,"title":1},"16":{"body":54,"breadcrumbs":1,"title":1},"17":{"body":76,"breadcrumbs":1,"title":1},"18":{"body":76,"breadcrumbs":1,"title":1},"19":{"body":107,"breadcrumbs":1,"title":1},"2":{"body":103,"breadcrumbs":2,"title":2},"20":{"body":44,"breadcrumbs":1,"title":1},"21":{"body":79,"breadcrumbs":5,"title":5},"22":{"body":90,"breadcrumbs":1,"title":1},"23":{"body":0,"breadcrumbs":3,"title":3},"24":{"body":115,"breadcrumbs":4,"title":4},"25":{"body":92,"breadcrumbs":5,"title":5},"26":{"body":0,"breadcrumbs":4,"title":4},"27":{"body":125,"breadcrumbs":4,"title":4},"28":{"body":126,"breadcrumbs":5,"title":5},"29":{"body":90,"breadcrumbs":4,"title":4},"3":{"body":127,"breadcrumbs":5,"title":5},"30":{"body":151,"breadcrumbs":2,"title":2},"31":{"body":9,"breadcrumbs":3,"title":3},"32":{"body":16,"breadcrumbs":1,"title":1},"33":{"body":14,"breadcrumbs":1,"title":1},"34":{"body":25,"breadcrumbs":1,"title":1},"35":{"body":25,"breadcrumbs":1,"title":1},"36":{"body":31,"breadcrumbs":1,"title":1},"37":{"body":33,"breadcrumbs":1,"title":1},"38":{"body":70,"breadcrumbs":1,"title":1},"39":{"body":20,"breadcrumbs":1,"title":1},"4":{"body":43,"breadcrumbs":1,"title":1},"40":{"body":39,"breadcrumbs":1,"title":1},"41":{"body":8,"breadcrumbs":1,"title":1},"42":{"body":30,"breadcrumbs":1,"title":1},"43":{"body":30,"breadcrumbs":1,"title":1},"44":{"body":36,"breadcrumbs":1,"title":1},"45":{"body":22,"breadcrumbs":1,"title":1},"46":{"body":19,"breadcrumbs":1,"title":1},"47":{"body":19,"breadcrumbs":1,"title":1},"48":{"body":52,"breadcrumbs":2,"title":2},"49":{"body":76,"breadcrumbs":1,"title":1},"5":{"body":25,"breadcrumbs":4,"title":4},"50":{"body":291,"breadcrumbs":7,"title":7},"51":{"body":332,"breadcrumbs":5,"title":5},"52":{"body":50,"breadcrumbs":2,"title":2},"53":{"body":152,"breadcrumbs":1,"title":1},"54":{"body":270,"breadcrumbs":7,"title":7},"55":{"body":263,"breadcrumbs":5,"title":5},"56":{"body":29,"breadcrumbs":3,"title":3},"57":{"body":45,"breadcrumbs":3,"title":3},"58":{"body":124,"breadcrumbs":4,"title":4},"59":{"body":182,"breadcrumbs":4,"title":4},"6":{"body":51,"breadcrumbs":2,"title":2},"60":{"body":144,"breadcrumbs":5,"title":5},"7":{"body":11,"breadcrumbs":2,"title":2},"8":{"body":51,"breadcrumbs":1,"title":1},"9":{"body":223,"breadcrumbs":2,"title":2}},"docs":{"0":{"body":"ArrayFire is a high performance software library for parallel computing with an easy-to-use API. ArrayFire abstracts away much of the details of programming parallel architectures by providing a high-level container object, the Array , that represents data stored on a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write massively parallel applications in a high-level language where they need not be concerned about low-level optimizations that are frequently required to achieve high throughput on most parallel architectures. ArrayFire provides one generic container object, the Array on which functions and mathematical operations are performed. The Array can represent one of many different basic data types : F32 real single-precision (float) C32 complex single-precision (cfloat) F64 real double-precision (double) C64 complex double-precision (cdouble) B8 8-bit boolean values (bool) S32 32-bit signed integer (int) U32 32-bit unsigned integer (unsigned) U8 8-bit unsigned values (unsigned char) S64 64-bit signed integer (intl) U64 64-bit unsigned integer (uintl) S16 16-bit signed integer (short) U16 16-bit unsigned integer (unsigned short) F16 16-bit floating point number ( half::f16 ) Most of these data types are supported on all modern GPUs; however, some older devices may lack support for double precision arrays. In this case, a runtime error will be generated when the array is constructed. If not specified, Arrays are created as single precision floating point numbers ( F32 ).","breadcrumbs":"Supported data types","id":"0","title":"Supported data types"},"1":{"body":"ArrayFire Array 's represent memory stored on the device. As such, creation and population of an array will consume memory on the device which cannot freed until the array object goes out of scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which will re-use device memory whenever possible. Arrays can be created using one of the array constructors . Below we show how to create 1D, 2D, and 3D arrays with uninitialized values: let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32); However, uninitialized memory is likely not useful in your application. ArrayFire provides several convenient functions for creating arrays that contain pre-populated values including constants, uniform random numbers, uniform normally distributed numbers, and the identity matrix: // Create an array filled with constant value of 2.0 of type floating point\n// The type of Array is infered from the type of the constant argument\nlet cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1]));\nprint(&cnst); println!(\"Create a 5-by-3 matrix of random floats on the GPU\");\nlet dims = Dim4::new(&[5, 3, 1, 1]);\nlet a = randu::(dims);\nprint(&a); As stated above, the default data type for arrays is F32 (32-bit floating point number) unless specified otherwise. ArrayFire Arrays may also be populated from data found on the host. For example: let values: [u32; 3] = [1u32, 2, 3];\nlet indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));\nprint(&indices);","breadcrumbs":"Creating and populating an Array","id":"1","title":"Creating and populating an Array"},"10":{"body":"This construct is similar to gfor loop from C++ API of ArrayFire. It has not been implemented in rust wrapper. This section will be updated once the feature has been added to the crate.","breadcrumbs":"GFOR","id":"10","title":"GFOR"},"11":{"body":"This another pending feature that is similar to our C++ API of batchFunc()","breadcrumbs":"batch_func","id":"11","title":"batch_func"},"12":{"body":"ArrayFire provides several different methods for manipulating arrays and matrices. The functionality includes: moddims() - change the dimensions of an array without changing the data flat() - flatten an array to one dimension flip() - flip an array along a dimension join() - join up to 4 arrays reorder() - changes the dimension order within the array shift() - shifts data along a dimension tile() - repeats an array along a dimension transpose() - performs a matrix transpose Below we provide several examples of these functions and their use.","breadcrumbs":"Array and Matrix Manipulation","id":"12","title":"Array and Matrix Manipulation"},"13":{"body":"The moddims function changes the dimensions of an array without changing its data or order. Note that this function modifies only the metadata associated with the array. It does not modify the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and then back to a 8x1: a [8 1 1 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 let new_dims = Dim4::new(&[2, 4, 1, 1]);\nmoddims(&a, new_dims)\n[2 4 1 1] 1.0000 1.0000 1.0000 1.0000 2.0000 2.0000 2.0000 2.0000 let out = moddims(&a, a.elements(), 1, 1, 1);\n[8 1 1 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000","breadcrumbs":"moddims()","id":"13","title":"moddims()"},"14":{"body":"The flat function flattens an array to one dimension: a [3 3 1 1] 1.0000 4.0000 7.0000 2.0000 5.0000 8.0000 3.0000 6.0000 9.0000 flat(&a)\n[9 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000","breadcrumbs":"flat()","id":"14","title":"flat()"},"15":{"body":"The flip function flips the contents of an array along a chosen dimension. In the example below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. across rows) axes: a [5 2 1 1] 1.0000 6.0000 2.0000 7.0000 3.0000 8.0000 4.0000 9.0000 5.0000 10.0000 flip(a, 0) [5 2 1 1] 5.0000 10.0000 4.0000 9.0000 3.0000 8.0000 2.0000 7.0000 1.0000 6.0000 flip(a, 1) [5 2 1 1] 6.0000 1.0000 7.0000 2.0000 8.0000 3.0000 9.0000 4.0000 10.0000 5.0000","breadcrumbs":"flip()","id":"15","title":"flip()"},"16":{"body":"The join , join_many functions can be used to join arrays along a specific dimension. Here is an example of how to use join an array to itself: a [5 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 join(0, a, a) [10 1 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 join(1, a, a) [5 2 1 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 4.0000 4.0000 5.0000 5.0000","breadcrumbs":"join()","id":"16","title":"join()"},"17":{"body":"The reorder function modifies the order of data within an array by exchanging data according to the change in dimensionality. The linear ordering of data within the array is preserved. a [2 2 3 1] 1.0000 3.0000 2.0000 4.0000 1.0000 3.0000 2.0000 4.0000 1.0000 3.0000 2.0000 4.0000 reorder(&a, 1, 0, 2)\n[2 2 3 1] //equivalent to a transpose 1.0000 2.0000 3.0000 4.0000 1.0000 2.0000 3.0000 4.0000 1.0000 2.0000 3.0000 4.0000 reorder(&a, 2, 0, 1)\n[3 2 2 1] 1.0000 2.0000 1.0000 2.0000 1.0000 2.0000 3.0000 4.0000 3.0000 4.0000 3.0000 4.0000","breadcrumbs":"reorder()","id":"17","title":"reorder()"},"18":{"body":"The shift function shifts data in a circular buffer fashion along a chosen dimension. Consider the following example: a [3 5 1 1] 0.0000 0.0000 0.0000 0.0000 0.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 shift(&a, 0, 2 )\n[3 5 1 1] 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 shift(&a, -1, 2 )\n[3 5 1 1] 1.0000 2.0000 3.0000 4.0000 5.0000 1.0000 2.0000 3.0000 4.0000 5.0000 0.0000 0.0000 0.0000 0.0000 0.0000","breadcrumbs":"shift()","id":"18","title":"shift()"},"19":{"body":"The tile function repeats an array along the specified dimension. For example below we show how to tile an array along the zeroth and first dimensions of an array: a [3 1 1 1] 1.0000 2.0000 3.0000 // Repeat array a twice in the zeroth dimension\ntile(&a, 2)\n[6 1 1 1] 1.0000 2.0000 3.0000 1.0000 2.0000 3.0000 // Repeat array a twice along both the zeroth and first dimensions\ntile(&a, 2, 2)\n[6 2 1 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 // Repeat array a twice along the first and three times along the second\n// dimension.\nlet tile_dims = Dim4::new(&[1, 2, 3, 1]);\ntile(a, tile_dims) [3 2 3 1] 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000 1.0000 1.0000 2.0000 2.0000 3.0000 3.0000","breadcrumbs":"tile()","id":"19","title":"tile()"},"2":{"body":"ArrayFire provides several functions to determine various aspects of arrays. This includes functions to print the contents, query dimensions, and determine various other aspects of arrays. The print function can be used to print arrays that have already been generated or any expression involving arrays: let values: [f32; 3] = [1.0, 2.0, 3.0];\nlet indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));\nprint(&indices); The dimensions of an array may be determined using either a Dim4 object or by accessing the dimensions directly using the Dim4::get and Dim4::numdims functions: let values: [f32; 3] = [1.0, 2.0, 3.0];\nlet dims: Dim4 = Dim4::new(&[3, 1, 1, 1]);\nlet indices = Array::new(&values, dims);\nprintln!(\"Dims {:?} with dimensions {}\", dims.get(), dims.ndims()); In addition to dimensions, arrays also carry several properties including methods to determine the underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you consult the full documentation on the Array .","breadcrumbs":"Properties of an Array","id":"2","title":"Properties of an Array"},"20":{"body":"The transpose function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix. a [3 3 1 1] 1.0000 3.0000 3.0000 2.0000 1.0000 3.0000 2.0000 2.0000 1.0000 transpose(&a, False) //Second parameter to be used for conjugate transpose\n[3 3 1 1] 1.0000 2.0000 2.0000 3.0000 1.0000 2.0000 3.0000 3.0000 1.0000","breadcrumbs":"transpose()","id":"20","title":"transpose()"},"21":{"body":"By using a combination of the functions, one can quickly code complex manipulation patterns with a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small combination of the above functions. let a = iota::(Dim4::new(&[3, 1, 1, 1]), Dim4::new(&[1, 3, 1, 1]));\nlet b = transpose(&a, false);\nlet coords = join(1, &flat(&a), &flat(&b));\nprint(&coords); The output for a [3 3 1 1] matrix will be the following. [9 2 1 1] 0 0 1 0 2 0 0 1 1 1 2 1 0 2 1 2 2 2","breadcrumbs":"Combining functions to enumerate grid coordinates","id":"21","title":"Combining functions to enumerate grid coordinates"},"22":{"body":"Indexing in ArrayFire is a powerful but easy to abuse feature. This feature allows you to reference or copy subsections of a larger array and perform operations on only a subset of elements. This chapter is split into the following sections: Index an Array using Seq Objects Create a view of an existing Array Modify a sub region of an existing Array Using Array and Seq combination Create a view of an existing Array Modify a sub region of an existing Array Extract or Set rows/columns of an Array Negative Indices Indexer structure is the key element used in Rust wrapper of ArrayFire for creating references to existing Arrays. The above sections illustrate how it can be used in conjunction with Seq and/or Array. Apart from that, each section also showcases a macro based equivalent code(if one exists) that is more terse in syntax but offers the same functionality.","breadcrumbs":"Indexing","id":"22","title":"Indexing"},"23":{"body":"","breadcrumbs":"Using Seq objects","id":"23","title":"Using Seq objects"},"24":{"body":"We will Sequences and the function index in this approach. let dims = Dim4::new(&[5, 5, 1, 1]); let a = randu::(dims); //af_print!(\"a\", a); //a //[5 5 1 1] // 0.3990 0.5160 0.8831 0.9107 0.6688 // 0.6720 0.3932 0.0621 0.9159 0.8434 // 0.5339 0.2706 0.7089 0.0231 0.1328 // 0.1386 0.9455 0.9434 0.2330 0.2657 // 0.7353 0.1587 0.1227 0.2220 0.2299 // Index array using sequences let seqs = &[Seq::new(1u32, 3, 1), Seq::default()]; let _sub = index(&a, seqs); //af_print!(\"a(seq(1,3,1), span)\", sub); // [3 5 1 1] // 0.6720 0.3932 0.0621 0.9159 0.8434 // 0.5339 0.2706 0.7089 0.0231 0.1328 // 0.1386 0.9455 0.9434 0.2330 0.2657 However, the same above code can be condensed into a much terse syntax with the help of view macro. Take a look at the following two approaches using view macro. let dims = dim4!(5, 5, 1, 1); let a = randu::(dims); let first3 = seq!(1:3:1); let allindim2 = seq!(); let _sub = view!(a[first3, allindim2]); OR let a = randu::(dim4!(5, 5)); let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis","breadcrumbs":"Create a view of an existing Array","id":"24","title":"Create a view of an existing Array"},"25":{"body":"Let us take a look at an example where a portion of an existing Array will be set to with another Array. We will an constant value Array and the function assign_seq in the below example. let mut a = constant(2.0 as f32, dim4!(5, 3)); //print(&a); // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 // 2.0 2.0 2.0 let b = constant(1.0 as f32, dim4!(3, 3)); let seqs = [seq!(1:3:1), seq!()]; assign_seq(&mut a, &seqs, &b); //print(&a); // 2.0 2.0 2.0 // 1.0 1.0 1.0 // 1.0 1.0 1.0 // 1.0 1.0 1.0 // 2.0 2.0 2.0 A much terser way of doing the same using macro is shown below let mut a = randu::(dim4!(5, 5)); let b = randu::(dim4!(2, 2)); eval!(a[1:2:1, 1:2:1] = b); NOTE Normally you want to avoid accessing individual elements of the array like this for performance reasons.","breadcrumbs":"Modify a sub region of an existing Array","id":"25","title":"Modify a sub region of an existing Array"},"26":{"body":"","breadcrumbs":"Using Array and Seq combination","id":"26","title":"Using Array and Seq combination"},"27":{"body":"To use a combination of Array and Seq objects to index an existing Array, we will need a more generalized function index_gen . let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); let seq4gen = Seq::new(0.0, 2.0, 1.0); let a = randu::(Dim4::new(&[5, 3, 1, 1])); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 // 0.5328 0.9347 0.0535 let mut idxrs = Indexer::default(); idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation let _sub2 = index_gen(&a, idxrs); //println!(\"a(indices, seq(0, 2, 1))\"); print(&sub2); // [3 3 1 1] // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 Similar to how view macro helped with abreviating the syntax when indexing with just sequences, it can also help when using a combination of Seq and Array. let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); let seq4gen = seq!(0:2:1); let a = randu::(Dim4::new(&[5, 3, 1, 1])); let _sub2 = view!(a[indices, seq4gen]);","breadcrumbs":"Create a view of an existing Array","id":"27","title":"Create a view of an existing Array"},"28":{"body":"Set a portion of an existing Array with another Array using a combination of Seq and Array. We will use assign_gen function to do it. let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, dim4!(3, 1, 1, 1)); let seq4gen = seq!(0:2:1); let mut a = randu::(dim4!(5, 3, 1, 1)); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 0.1315 0.0470 0.5194 // 0.7556 0.6789 0.8310 // 0.4587 0.6793 0.0346 // 0.5328 0.9347 0.0535 let b = constant(2.0 as f32, dim4!(3, 3, 1, 1)); let mut idxrs = Indexer::default(); idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation let _sub2 = assign_gen(&mut a, &idxrs, &b); //println!(\"a(indices, seq(0, 2, 1))\"); print(&sub2); // [5 3 1 1] // 0.0000 0.2190 0.3835 // 2.0000 2.0000 2.0000 // 2.0000 2.0000 2.0000 // 2.0000 2.0000 2.0000 // 0.5328 0.9347 0.0535 OR let values: [f32; 3] = [1.0, 2.0, 3.0]; let indices = Array::new(&values, dim4!(3)); let seq4gen = seq!(0:2:1); let mut a = randu::(dim4!(5, 3)); let b = constant(2.0 as f32, dim4!(3, 3)); eval!(a[indices, seq4gen] = b);","breadcrumbs":"Modify a sub region of an existing Array","id":"28","title":"Modify a sub region of an existing Array"},"29":{"body":"Extract a specific set of rows/coloumns from an existing Array. let a = randu::(dim4!(5, 5, 1, 1)); //print(&a); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = row(&a, 4); // [1 5 1 1] // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = col(&a, 4); // [5 1 1 1] // 0.6755 // 0.6105 // 0.5232 // 0.5567 // 0.7896 You can also use rows & cols to retrieve a subset of rows or coloumns respectively. Similarly, set_row & set_rows can be used to change the values in a particular set of rows using another Array. set_col & set_cols has same functionality, except that it is for coloumns.","breadcrumbs":"Extract or Set rows/columns of an Array","id":"29","title":"Extract or Set rows/columns of an Array"},"3":{"body":"ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, ArrayFire functions like a vector library. That means that an element-wise operation, like c[i] = a[i] + b[i] in C, would be written more concisely without indexing, like c = a + b. When there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. his \"kernel fusion\" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations. Our JIT functionality extends across C API boundary and only ends when a non-JIT function is encountered or a synchronization operation is explicitly called by the code. ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators (e.g. +,-,*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples: let num_rows: u64 = 5;\nlet num_cols: u64 = 3;\nlet dims = Dim4::new(&[num_rows, num_cols, 1, 1]);\nlet a = randu::(dims);\nlet b = randu::(dims);\nprint(&a);\nprint(&b);\nlet c = a + b;\nprint(&c); //Example of *Assign traits\nlet mut d = randu::(dims);\nlet e = constant(1f32, dims);\nd += e;\nprint(&d);","breadcrumbs":"Writing math expressions using ArrayFire","id":"3","title":"Writing math expressions using ArrayFire"},"30":{"body":"Negative indices can also be used to refer elements from the end of a given axis. Negative value for a row/column/slice will fetch corresponding row/column/slice in reverse order. Given below are some examples that showcase getting row(s)/col(s) from an existing Array. let a = randu::(dim4!(5, 5)); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = row(&a, -1); // [1 5 1 1] // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = col(&a, -1); // [5 1 1 1] // 0.6755 // 0.6105 // 0.5232 // 0.5567 // 0.7896 let a = randu::(dim4!(5, 5)); // [5 5 1 1] // 0.6010 0.5497 0.1583 0.3636 0.6755 // 0.0278 0.2864 0.3712 0.4165 0.6105 // 0.9806 0.3410 0.3543 0.5814 0.5232 // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _r = rows(&a, -1, -2); // [2 5 1 1] // 0.2126 0.7509 0.6450 0.8962 0.5567 // 0.0655 0.4105 0.9675 0.3712 0.7896 let _c = cols(&a, -1, -3); // [5 3 1 1] // 0.1583 0.3636 0.6755 // 0.3712 0.4165 0.6105 // 0.3543 0.5814 0.5232 // 0.6450 0.8962 0.5567 // 0.9675 0.3712 0.7896","breadcrumbs":"Negative Indices","id":"30","title":"Negative Indices"},"31":{"body":"Following are the list of environment and runtime configurations that will help enhance your experience with ArrayFire.","breadcrumbs":"Configuring Arrayfire Environment","id":"31","title":"Configuring Arrayfire Environment"},"32":{"body":"This is the path with ArrayFire gets installed, ie. the includes and libs are present in this directory. You can use this variable to add include paths and libraries to your projects.","breadcrumbs":"AF_PATH","id":"32","title":"AF_PATH"},"33":{"body":"When AF\\_PRINT\\_ERRORS is set to 1, the exceptions thrown are more verbose and detailed. This helps in locating the exact failure. AF_PRINT_ERRORS=1 ./myprogram","breadcrumbs":"AF_PRINT_ERRORS","id":"33","title":"AF_PRINT_ERRORS"},"34":{"body":"Use this variable to set the default CUDA device. Valid values for this variable are the device identifiers shown when info is run. AF_CUDA_DEFAULT_DEVICE=1 ./myprogram Note: set_device call in the source code will take precedence over this variable.","breadcrumbs":"AF_CUDA_DEFAULT_DEVICE","id":"34","title":"AF_CUDA_DEFAULT_DEVICE"},"35":{"body":"Use this variable to set the default OpenCL device. Valid values for this variable are the device identifiers shown when info is run. AF_OPENCL_DEFAULT_DEVICE=1 ./myprogram Note: set_device call in the source code will take precedence over this variable.","breadcrumbs":"AF_OPENCL_DEFAULT_DEVICE","id":"35","title":"AF_OPENCL_DEFAULT_DEVICE"},"36":{"body":"Use this variable to set the default OpenCL device type. Valid values for this variable are: CPU, GPU, ACC (Accelerators). When set, the first device of the specified type is chosen as default device. AF_OPENCL_DEFAULT_DEVICE_TYPE=CPU ./myprogram Note: AF_OPENCL_DEFAULT_DEVICE and set_device takes precedence over this variable.","breadcrumbs":"AF_OPENCL_DEFAULT_DEVICE_TYPE","id":"36","title":"AF_OPENCL_DEFAULT_DEVICE_TYPE"},"37":{"body":"Use this variable to only choose OpenCL devices of specified type. Valid values for this variable are: ALL: All OpenCL devices. (Default behavior). CPU: CPU devices only. GPU: GPU devices only. ACC: Accelerator devices only. When set, the remaining OpenCL device types are ignored by the OpenCL backend. AF_OPENCL_DEVICE_TYPE=CPU ./myprogram","breadcrumbs":"AF_OPENCL_DEVICE_TYPE","id":"37","title":"AF_OPENCL_DEVICE_TYPE"},"38":{"body":"When ArrayFire runs on devices with unified memory with the host (ie. CL_DEVICE_HOST_UNIFIED_MENORY is true for the device) then certain functions are offloaded to run on the CPU using mapped buffers. ArrayFire takes advantage of fast libraries such as MKL while spending no time copying memory from device to host. The device memory is mapped to a host pointer which can be used in the offloaded functions. This functionality can be disabled by using the environment variable AF_OPENCL_CPU_OFFLOAD=0. The default bevaior of this has changed in version 3.4. Prior to v3.4, CPU Offload functionality was used only when the user set AF_OPENCL_CPU_OFFLOAD=1 and disabled otherwise. From v3.4 onwards, CPU Offload is enabled by default and is disabled only when AF_OPENCL_CPU_OFFLOAD=0 is set.","breadcrumbs":"AF_OPENCL_CPU_OFFLOAD","id":"38","title":"AF_OPENCL_CPU_OFFLOAD"},"39":{"body":"This variable is useful when debuggin OpenCL kernel compilation failures. When this variable is set to 1, and an error occurs during a OpenCL kernel compilation, then the log and kernel are printed to screen.","breadcrumbs":"AF_OPENCL_SHOW_BUILD_INFO","id":"39","title":"AF_OPENCL_SHOW_BUILD_INFO"},"4":{"body":"Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To index Arrays you may use one or a combination of the following functions: Seq representing a linear sequence Seq::Default() representing the entire dimension row(&Array, i) or col(&Array, i) specifying a single row/column rows(&Array, first,last) or cols(&Array, first,last) specifying a span of rows or columns Please see the indexing page for several examples of how to use these functions.","breadcrumbs":"Indexing","id":"4","title":"Indexing"},"40":{"body":"Setting this variable to 1 will disable window creation when graphics functions are being called. Disabling window creation will disable all other graphics calls at runtime. This is a useful when running code on servers and systems without displays. When graphics calls are run on such machines, they will print warning about window creation failing. To suppress those calls, set this variable.","breadcrumbs":"AF_DISABLE_GRAPHICS","id":"40","title":"AF_DISABLE_GRAPHICS"},"41":{"body":"When this environment variable is set to 1, ArrayFire will execute all functions synchronously.","breadcrumbs":"AF_SYNCHRONOUS_CALLS","id":"41","title":"AF_SYNCHRONOUS_CALLS"},"42":{"body":"When using the Unified backend, if this variable is set to 1, it will show the path where the ArrayFire backend libraries are loaded from. If the libraries are loaded from system paths, such as PATH or LD_LIBRARY_PATH etc, then it will print \"system path\". If the libraries are loaded from other paths, then those paths are shown in full.","breadcrumbs":"AF_SHOW_LOAD_PATH","id":"42","title":"AF_SHOW_LOAD_PATH"},"43":{"body":"When AF_MEM_DEBUG is set to 1 (or anything not equal to 0), the caching mechanism in the memory manager is disabled. The device buffers are allocated using native functions as needed and freed when going out of scope. When the environment variable is not set, it is treated to be non zero. AF_MEM_DEBUG=1 ./myprogram","breadcrumbs":"AF_MEM_DEBUG","id":"43","title":"AF_MEM_DEBUG"},"44":{"body":"When AF_MAX_BUFFERS is set, this environment variable specifies the maximum number of buffers allocated before garbage collection kicks in. Please note that the total number of buffers that can exist simultaneously can be higher than this number. This variable tells the garbage collector that it should free any available buffers immediately if the treshold is reached. When not set, the default value is 1000.","breadcrumbs":"AF_MAX_BUFFERS","id":"44","title":"AF_MAX_BUFFERS"},"45":{"body":"When set, this environment variable specifies the maximum height of the OpenCL JIT tree after which evaluation is forced. The default value, as of v3.4, is 50 on OSX, 100 everywhere else. This value was 20 for older versions.","breadcrumbs":"AF_OPENCL_MAX_JIT_LEN","id":"45","title":"AF_OPENCL_MAX_JIT_LEN"},"46":{"body":"When set, this environment variable specifies the maximum height of the CUDA JIT tree after which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.","breadcrumbs":"AF_CUDA_MAX_JIT_LEN","id":"46","title":"AF_CUDA_MAX_JIT_LEN"},"47":{"body":"When set, this environment variable specifies the maximum length of the CPU JIT tree after which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions.","breadcrumbs":"AF_CPU_MAX_JIT_LEN","id":"47","title":"AF_CPU_MAX_JIT_LEN"},"48":{"body":"Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to increase your productivity, or you may need to supplement ArrayFire's functionality with your own custom implementation of specific algorithms. ArrayFire manages its own memory, runs within its own CUDA stream, and creates custom IDs for devices. As such, most of the interoperability functions focus on reducing potential synchronization conflicts between ArrayFire and CUDA.","breadcrumbs":"Interoperability with CUDA","id":"48","title":"Interoperability with CUDA"},"49":{"body":"It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides several functions to ease this process including: Function Purpose Array::new_from_device_ptr Construct an ArrayFire Array from device memory Array::device_ptr Obtain a pointer to the device memory (implies lock()) Array::lock Removes ArrayFire's control of a device memory pointer Array::unlock Restores ArrayFire's control over a device memory pointer get_device Gets the current ArrayFire device ID set_device Switches ArrayFire to the specified device get_device_native_id Fetches CUDA deviceID for a given ArrayFire device ID set_device_native_id Switches active device to the specified CUDA device ID get_stream Get the current CUDA stream used by ArrayFire","breadcrumbs":"Basics","id":"49","title":"Basics"},"5":{"body":"Memory in af::Arrays may be accessed using the Array::host() method. The host function copies the data from the device and makes it available in a standard slice or similar container on the host. As such, it is up to the developer to manage any memory returned by host.","breadcrumbs":"Access to Array memory on the host","id":"5","title":"Access to Array memory on the host"},"50":{"body":"By default, ArrayFire manages its own memory and operates in its own CUDA stream. Thus there is a slight amount of bookkeeping that needs to be done in order to integrate your custom CUDA kernel. Ideally, we recommend using ArrayFire's CUDA stream to launch your custom kernels. However, this is currently not possible due to limitation on RustaCUDA not being to able to wrap an existing cudaStream_t/CUstream_t objects. The current work around is to create a stream of your own and launch the kernel on it. Notice that since ArrayFire and your kernels are not sharing the same CUDA stream, there is a need to perform explicit synchronization before launching kernel on your stream that depends on the computation carried out by ArrayFire earlier. This extra step is unnecessary once the above stated limiation of RustaCUDA's stream is eliminated. This process is best illustrated with a fully worked example: use arrayfire as af;\nuse rustacuda::prelude::*;\nuse rustacuda::*; use std::ffi::CString; fn main() { // MAKE SURE to do all rustacuda initilization before arrayfire API's // first call. It seems like some CUDA context state is getting messed up // if we mix CUDA context init(device, context, module, stream) with ArrayFire API match rustacuda::init(CudaFlags::empty()) { Ok(()) => {} Err(e) => panic!(\"rustacuda init failure: {:?}\", e), } let device = match Device::get_device(0) { Ok(d) => d, Err(e) => panic!(\"Failed to get device: {:?}\", e), }; let _context = match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { Ok(c) => c, Err(e) => panic!(\"Failed to create context: {:?}\", e), }; let ptx = CString::new(include_str!(\"./resources/add.ptx\")).unwrap(); let module = match Module::load_from_string(&ptx) { Ok(m) => m, Err(e) => panic!(\"Failed to load module from string: {:?}\", e), }; let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { Ok(s) => s, Err(e) => panic!(\"Failed to create stream: {:?}\", e), }; af::set_device(0); af::info(); let num: i32 = 10; let x = af::constant(1f32, af::dim4!(10)); let y = af::constant(2f32, af::dim4!(10)); let out = af::constant(0f32, af::dim4!(10)); af::af_print!(\"x\", x); af::af_print!(\"y\", y); af::af_print!(\"out(init)\", out); //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda // let af_id = get_device(); // let cuda_id = get_device_native_id(af_id); // let af_cuda_stream = get_stream(cuda_id); //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda // let stream = Stream {inner: mem::transmute(af_cuda_stream)}; // Run a custom CUDA kernel in the ArrayFire CUDA stream unsafe { // Obtain device pointers from ArrayFire using Array::device() method let d_x: *mut f32 = x.device_ptr() as *mut f32; let d_y: *mut f32 = y.device_ptr() as *mut f32; let d_o: *mut f32 = out.device_ptr() as *mut f32; match launch!(module.sum<<<1, 1, 0, stream>>>( memory::DevicePointer::wrap(d_x), memory::DevicePointer::wrap(d_y), memory::DevicePointer::wrap(d_o), num )) { Ok(()) => {} Err(e) => panic!(\"Kernel Launch failure: {:?}\", e), } // wait for the kernel to finish as it is async call match stream.synchronize() { Ok(()) => {} Err(e) => panic!(\"Stream sync failure: {:?}\", e), }; // Return control of Array memory to ArrayFire using unlock x.unlock(); y.unlock(); out.unlock(); } af::af_print!(\"sum after kernel launch\", out);\n}","breadcrumbs":"Using custom CUDA kernels in existing ArrayFire application","id":"50","title":"Using custom CUDA kernels in existing ArrayFire application"},"51":{"body":"Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due to several optimizations we implement. The most important are as follows: ArrayFire assumes control of all memory provided to it. ArrayFire does not (in general) support in-place memory transactions. We will discuss the implications of these items below. To add ArrayFire to existing code you need to: Finish any pending CUDA operations (e.g. cudaDeviceSynchronize() or similar stream functions) Create ArrayFire arrays from existing CUDA pointers Perform operations on ArrayFire arrays Instruct ArrayFire to finish operations using eval and sync Obtain pointers to important memory Continue your CUDA application. Free non-managed memory To create the Array fom device pointer, you should use one of the following approaches: Using DeviceBuffer from RustaCUDA , or a Wrapper Object for CUDA device memory let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap(); let array_dptr = Array::new_from_device_ptr( buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10)); array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership Using raw pointer returned from cuda_malloc interface exposed by RustaCUDA let mut dptr: *mut f32 = std::ptr::null_mut();\nunsafe { dptr = memory::cuda_malloc::(10*10).unwrap().as_raw_mut();\n} let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));\n// After ArrayFire takes over ownership of the pointer, you can use other\n// arrayfire functions as usual. ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. Thus ArrayFire could free or reuse the memory at any later time. If this behavior is not desired, you may call Array::unlock and manage the memory yourself. However, if you do so, please be cautious not to free memory when ArrayFire might be using it! The seven steps above are best illustrated using a fully-worked example: use arrayfire::{af_print, dim4, info, set_device, Array};\nuse rustacuda::prelude::*; fn main() { // MAKE SURE to do all rustacuda initilization before arrayfire API's // first call. It seems like some CUDA context state is getting messed up // if we mix CUDA context init(device, context, module, stream) with ArrayFire API match rustacuda::init(CudaFlags::empty()) { Ok(()) => {} Err(e) => panic!(\"rustacuda init failure: {:?}\", e), } let device = match Device::get_device(0) { Ok(d) => d, Err(e) => panic!(\"Failed to get device: {:?}\", e), }; let _context = match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { Ok(c) => c, Err(e) => panic!(\"Failed to create context: {:?}\", e), }; let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { Ok(s) => s, Err(e) => panic!(\"Failed to create stream: {:?}\", e), }; let mut in_x = DeviceBuffer::from_slice(&[1.0f32; 10]).unwrap(); let mut in_y = DeviceBuffer::from_slice(&[2.0f32; 10]).unwrap(); // wait for any prior kernels to finish before passing // the device pointers to ArrayFire match stream.synchronize() { Ok(()) => {} Err(e) => panic!(\"Stream sync failure: {:?}\", e), }; set_device(0); info(); let x = Array::new_from_device_ptr(in_x.as_device_ptr().as_raw_mut(), dim4!(10)); let y = Array::new_from_device_ptr(in_y.as_device_ptr().as_raw_mut(), dim4!(10)); // Lock so that ArrayFire doesn't free pointers from RustaCUDA // But we have to make sure these pointers stay in valid scope // as long as the associated ArrayFire Array objects are valid x.lock(); y.lock(); af_print!(\"x\", x); af_print!(\"y\", y); let o = x + y; af_print!(\"out\", o); let _o_dptr = unsafe { o.device_ptr() }; // Calls an implicit lock // User has to call unlock if they want to relenquish control to ArrayFire // Once the non-arrayfire operations are done, call unlock. o.unlock(); // After this, there is no guarantee that value of o_dptr is valid\n}","breadcrumbs":"Adding ArrayFire to existing CUDA Application","id":"51","title":"Adding ArrayFire to existing CUDA Application"},"52":{"body":"Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to increase your productivity, or you may need to supplement ArrayFire's functionality with your own custom implementation of specific algorithms. ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. As such, most of the interoperability functions focus on reducing potential synchronization conflicts between ArrayFire and OpenCL.","breadcrumbs":"Interoperability with OpenCL","id":"52","title":"Interoperability with OpenCL"},"53":{"body":"It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides several functions to ease this process including: Function Purpose Array::new_from_device_ptr Construct an ArrayFire Array from cl_mem Array::device_ptr Obtain a pointer to the device memory (implies lock) Array::lock Removes ArrayFire's control of a device memory pointer Array::unlock Restores ArrayFire's control over a device memory pointer get_platform Get ArrayFire's current cl_platform get_device Gets the current ArrayFire device ID get_device_id Get ArrayFire's current cl_device_id set_device_id Set ArrayFire's device from a cl_device_id set_device Switches ArrayFire to the specified device get_context Get ArrayFire's current cl_context get_queue Get ArrayFire's current cl_command_queue get_device_type Get the current DeviceType Note that the pointer returned by Array::device_ptr should be cast to cl_mem before using it with OpenCL opaque types. The pointer is a cl_mem internally that is force casted to pointer type by ArrayFire before returning the value to caller. Additionally, the OpenCL backend permits the programmer to add and remove custom devices from the ArrayFire device manager. These permit you to attach ArrayFire directly to the OpenCL queue used by other portions of your application. Function Purpose add_device_context Add a new device to ArrayFire's device manager set_device_context Set ArrayFire's device from cl_device_id & cl_context delete_device_context Remove a device from ArrayFire's device manager Below we provide two worked examples on how ArrayFire can be integrated into new and existing projects.","breadcrumbs":"Basics","id":"53","title":"Basics"},"54":{"body":"By default, ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. Thus there is some bookkeeping that needs to be done to integrate your custom OpenCL kernel. If your kernels can share operate in the same queue as ArrayFire, you should: Obtain the OpenCL context, device, and queue used by ArrayFire Obtain cl_mem references to Array objects Load, build, and use your kernels Return control of Array memory to ArrayFire Note, ArrayFire uses an in-order queue, thus when ArrayFire and your kernels are operating in the same queue, there is no need to perform any synchronization operations. This process is best illustrated with a fully worked example: //! A trivial example. Copied from ocl-core crate repository.\nuse af_opencl_interop as afcl;\nuse arrayfire as af; use ocl_core::{ArgVal, Event}; use std::ffi::CString; fn main() { af::info(); let dims = af::dim4!(8); let af_buffer = af::constant(0f32, dims.clone()); af::af_print!(\"af_buffer\", af_buffer); let src = r#\" __kernel void add(__global float* buffer, float scalar) { buffer[get_global_id(0)] += scalar; } \"#; let af_did = afcl::get_device_id(); let af_ctx = afcl::get_context(false); let af_que = afcl::get_queue(false); let _devid = unsafe { ocl_core::DeviceId::from_raw(af_did) }; let contx = unsafe { ocl_core::Context::from_raw_copied_ptr(af_ctx) }; let queue = unsafe { ocl_core::CommandQueue::from_raw_copied_ptr(af_que) }; // Define which platform and device(s) to use. Create a context, // queue, and program then define some dims.. let src_cstring = CString::new(src).unwrap(); let program = ocl_core::create_program_with_source(&contx, &[src_cstring]).unwrap(); ocl_core::build_program( &program, None::<&[()]>, &CString::new(\"\").unwrap(), None, None, ) .unwrap(); // Fetch cl_mem from ArrayFire Array let ptr = unsafe { af_buffer.device_ptr() }; let buffer = unsafe { ocl_core::Mem::from_raw_copied_ptr(ptr) }; // Create a kernel with arguments matching those in the source above: let kernel = ocl_core::create_kernel(&program, \"add\").unwrap(); ocl_core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap(); ocl_core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap(); let ocl_dims: [usize; 3] = [dims[0] as usize, dims[1] as usize, dims[2] as usize]; unsafe { ocl_core::enqueue_kernel( &queue, &kernel, 1, None, &ocl_dims, None, None::, None::<&mut Event>, ) .unwrap(); } ocl_core::finish(&queue).unwrap(); af_buffer.unlock(); //Give back control of cl_mem to ArrayFire memory manager af::af_print!(\"af_buffer after running Custom Kernel on it\", af_buffer);\n} If your kernels needs to operate in their own OpenCL queue, the process is essentially identical, except you need to instruct ArrayFire to complete its computations using the sync function prior to launching your own kernel and ensure your kernels are complete using clFinish (or similar) commands prior to returning control of the memory to ArrayFire: Obtain the OpenCL context, device, and queue used by ArrayFire Obtain cl_mem references to Array objects Instruct ArrayFire to finish operations using sync Load, build, and use your kernels Instruct OpenCL to finish operations using clFinish() or similar commands. Return control of Array memory to ArrayFire","breadcrumbs":"Adding custom OpenCL kernels to an existing ArrayFire application","id":"54","title":"Adding custom OpenCL kernels to an existing ArrayFire application"},"55":{"body":"Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due to several optimizations we implement. The most important are as follows: ArrayFire assumes control of all memory provided to it. ArrayFire does not (in general) support in-place memory transactions. We will discuss the implications of these items below. To add ArrayFire to existing code you need to: Instruct OpenCL to complete its operations using clFinish (or similar) Instruct ArrayFire to use the user-created OpenCL Context Create ArrayFire arrays from OpenCL memory objects Perform ArrayFire operations on the Array s Instruct ArrayFire to finish operations using sync Obtain cl_mem references for important memory Continue your OpenCL application ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. If you are creating an array from another RAII style object, you should retain it to ensure your memory is not deallocated if your RAII object were to go out of scope. If you do not wish for ArrayFire to manage your memory, you may call the Array::unlock function and manage the memory yourself; however, if you do so, please be cautious not to call clReleaseMemObj on a cl_mem when ArrayFire might be using it! Given below is a fully working example: //! A trivial example. Copied from ocl-core crate repository.\nuse af_opencl_interop as afcl;\nuse arrayfire as af; use ocl_core::{ContextProperties, Event}; fn main() { // Choose platform & device(s) to use. Create a context, queue, let platform_id = ocl_core::default_platform().unwrap(); let device_ids = ocl_core::get_device_ids(&platform_id, None, None).unwrap(); let device_id = device_ids[0]; let context_properties = ContextProperties::new().platform(platform_id); let context = ocl_core::create_context(Some(&context_properties), &[device_id], None, None).unwrap(); let queue = ocl_core::create_command_queue(&context, &device_id, None).unwrap(); let dims = [8, 1, 1]; // Create a `Buffer`: let mut vec = vec![0.0f32; dims[0]]; let buffer = unsafe { ocl_core::create_buffer( &context, ocl_core::MEM_READ_WRITE | ocl_core::MEM_COPY_HOST_PTR, dims[0], Some(&vec), ) .unwrap() }; ocl_core::finish(&queue).unwrap(); //sync up before switching to arrayfire // Add custom device, context and associated queue to ArrayFire afcl::add_device_context(device_id.as_raw(), context.as_ptr(), queue.as_ptr()); afcl::set_device_context(device_id.as_raw(), context.as_ptr()); af::info(); let mut af_buffer = af::Array::new_from_device_ptr( buffer.as_ptr() as *mut f32, af::Dim4::new(&[dims[0] as u64, 1, 1, 1]), ); af::af_print!(\"GPU Buffer before modification:\", af_buffer); af_buffer = af_buffer + 10f32; af::sync(af::get_device()); unsafe { let ptr = af_buffer.device_ptr(); let obuf = ocl_core::Mem::from_raw_copied_ptr(ptr); // Read results from the device into a vector: ocl_core::enqueue_read_buffer( &queue, &obuf, true, 0, &mut vec, None::, None::<&mut Event>, ) .unwrap(); } println!(\"GPU buffer on host after ArrayFire operation: {:?}\", vec); // Remove device from ArrayFire management towards Application Exit af::set_device(0); // Cannot pop when in Use, hence switch to another device afcl::delete_device_context(device_id.as_raw(), context.as_ptr());\n}","breadcrumbs":"Adding ArrayFire to an existing OpenCL application","id":"55","title":"Adding ArrayFire to an existing OpenCL application"},"56":{"body":"In this chapter, we will looking at how to use ArrayFire in multi-threaded programs. We shall go over the details in the following order. Move an Array to thread Read Array from Multiple threads Write to Array from Multiple threads Write to single Array using Channel","breadcrumbs":"ArrayFire in Threaded Applications","id":"56","title":"ArrayFire in Threaded Applications"},"57":{"body":"In this section, we are going to create an Array on main thread and move it to a child thread, modify it and then print it from the child thread. set_device(0); info(); let mut a = constant(1, dim4!(3, 3)); let handle = thread::spawn(move || { //set_device to appropriate device id is required in each thread set_device(0); println!(\"\\nFrom thread {:?}\", thread::current().id()); a += constant(2, dim4!(3, 3)); print(&a); }); //Need to join other threads as main thread holds arrayfire context handle.join().unwrap();","breadcrumbs":"Move an Array to thread","id":"57","title":"Move an Array to thread"},"58":{"body":"Now, let's expand the earlier example to do a bunch of arithmetic operations in parallel on multiple threads using the same Array objects. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); // ArrayFire Array's are internally maintained via atomic reference counting // Thus, they need no Arc wrapping while moving to another thread. // Just call clone method on the object and share the resulting clone object let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); let threads: Vec<_> = ops .into_iter() .map(|op| { let x = a.clone(); let y = b.clone(); thread::spawn(move || { set_device(0); //Both of objects are created on device 0 earlier match op { Op::Add => { let _c = x + y; } Op::Sub => { let _c = x - y; } Op::Div => { let _c = x / y; } Op::Mul => { let _c = x * y; } } sync(0); thread::sleep(std::time::Duration::new(1, 0)); }) }) .collect(); for child in threads { let _ = child.join(); } Given below is the definition of the enum Op we used in the example for illustration simplicity. #[derive(Debug, Copy, Clone)] enum Op { Add, Sub, Div, Mul, }","breadcrumbs":"Read Array from Multiple threads","id":"58","title":"Read Array from Multiple threads"},"59":{"body":"Let us further expand the earlier example by accumulating the results of the arithmetic operations into a single Array object. The code will differ from earlier section in couple of locations: In the main thread, we wrap the accumulating Array in a read-write lock (std::sync::RwLock) which is in turn wrapped in an atomically reference counted counter a.k.a std::sync::Arc. In the children threads, we use the guarded objects returned by RwLock's write method to access the accumulator Array. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); let c = constant(0.0f32, dim4!(3, 3)); let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); // Move ownership to RwLock and wrap in Arc since same object is to be modified let c_lock = Arc::new(RwLock::new(c)); // a and b are internally reference counted by ArrayFire. Unless there // is prior known need that they may be modified, you can simply clone // the objects pass them to threads let threads: Vec<_> = ops .into_iter() .map(|op| { let x = a.clone(); let y = b.clone(); let wlock = c_lock.clone(); thread::spawn(move || { //Both of objects are created on device 0 in main thread //Every thread needs to set the device that it is going to //work on. Note that all Array objects must have been created //on same device as of date this is written on. set_device(0); if let Ok(mut c_guard) = wlock.write() { match op { Op::Add => { *c_guard += x + y; } Op::Sub => { *c_guard += x - y; } Op::Div => { *c_guard += x / y; } Op::Mul => { *c_guard += x * y; } } } }) }) .collect(); for child in threads { let _ = child.join(); } //let read_guard = c_lock.read().unwrap(); //af_print!(\"C after threads joined\", *read_guard); //C after threads joined //[3 3 1 1] // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000","breadcrumbs":"Write to Array from Multiple threads","id":"59","title":"Write to Array from Multiple threads"},"6":{"body":"In addition to supporting standard mathematical functions, Arrays that contain integer data types also support bitwise operators including and, or, and shift etc. Operator traits for Array as well as separate functions are also defined to support various use cases. let dims = Dim4::new(&[5, 3, 1, 1]);\nlet a = randu::(dims);\nlet b = randu::(dims); print(&a);\nprint(&b); let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid\nlet d = bitand(&a, &b, false); print(&c);\nprint(&d);","breadcrumbs":"Bitwise operators","id":"6","title":"Bitwise operators"},"60":{"body":"In this section, we shall modify the example to use channel instead of data sharing. let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; let ops_len: usize = ops.len(); // Set active GPU/device on main thread on which // subsequent Array objects are created set_device(0); let mut c = constant(0.0f32, dim4!(3, 3)); let a = constant(1.0f32, dim4!(3, 3)); let b = constant(2.0f32, dim4!(3, 3)); let (tx, rx) = mpsc::channel(); let threads: Vec<_> = ops .into_iter() .map(|op| { // a and b are internally reference counted by ArrayFire. Unless there // is prior known need that they may be modified, you can simply clone // the objects pass them to threads let x = a.clone(); let y = b.clone(); let tx_clone = tx.clone(); thread::spawn(move || { //Both of objects are created on device 0 in main thread //Every thread needs to set the device that it is going to //work on. Note that all Array objects must have been created //on same device as of date this is written on. set_device(0); let c = match op { Op::Add => x + y, Op::Sub => x - y, Op::Div => x / y, Op::Mul => x * y, }; tx_clone.send(c).unwrap(); }) }) .collect(); for _i in 0..ops_len { c += rx.recv().unwrap(); } //Need to join other threads as main thread holds arrayfire context for child in threads { let _ = child.join(); } //af_print!(\"C after accumulating results\", &c); //[3 3 1 1] // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000 // 8.0000 8.0000 8.0000","breadcrumbs":"Write to single Array using Channel","id":"60","title":"Write to single Array using Channel"},"7":{"body":"Google Groups ArrayFire Services: Consulting | Support | Training ArrayFire Blogs Email: mailto:technical@arrayfire.com","breadcrumbs":"Where to go for help?","id":"7","title":"Where to go for help?"},"8":{"body":"Programmers and Data Scientists want to take advantage of fast and parallel computational devices. Writing vectorized code is necessary to get the best performance out of the current generation parallel hardware and scientific computing software. However, writing vectorized code may not be immediately intuitive. ArrayFire provides many ways to vectorize a given code segment. In this chapter, we present several methods to vectorize code using ArrayFire and discuss the benefits and drawbacks associated with each method.","breadcrumbs":"Vectorization","id":"8","title":"Vectorization"},"9":{"body":"By its very nature, ArrayFire is a vectorized library. Most functions operate on Arrays as a whole i.e. on all elements in parallel. For example consider the following code: let mut a = af::range(Dim::new(&[10, 1, 1, 1])); // [0, 9]\na = a + 1; // [1, 10] This code will result in a single kernel that operates on all 10 elements of a in parallel. A small subset of such vectorized ArrayFire functions are given below for quick reference: Operator Category Functions Arithmetic operations +, -, *, /, %, >>, << Logical operations &&, ||, <, >, ==, != etc. Numeric functions abs , floor , round , min , max , etc. Complex operations real , imag , conjg , etc. Exponential and logarithmic fns exp , log , expm1 , log1p , etc. Trigonometric functions sin , cos , tan , etc. Hyperbolic functions sinh , cosh , tanh , etc. In addition to element-wise operations, many other functions are also vectorized in ArrayFire. Notice that even functions that perform some form of aggregation (e.g. sum or min ), signal processing (like convolve ), and image processing functions (i.e. rotate etc.) all support vectorization on different columns or images. For example, if we have NUM images of size WIDTHxHEIGHT, one could convolve each image in a vector fashion as follows: let g_coef: [f32, 9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; let f = Array::new(g_coef, Dim4::new(&[3, 3, 1, 1]));\nlet filter = f * 1.0f32/16; let signal = randu(WIDTH, HEIGHT, NUM);\nlet conv = convolve2(signal, filter, ConvMode::DEFAULT, ConvDomain::AUTO); Similarly, one can rotate 100 images by 45 degrees in a single call using code like the following: // Construct an array of 100 WIDTH x HEIGHT images of random numbers\nlet imgs = randu(WIDTH, HEIGHT, 100); // Rotate all of the images in a single command\nlet rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR); Although most functions in ArrayFire do support vectorization, some do not. Most notably, all linear algebra functions. Even though they are not vectorized linear algebra operations, they still execute in parallel on your hardware. Using the built in vectorized operations should be the first and preferred method of vectorizing any code written with ArrayFire.","breadcrumbs":"Generic/Default vectorization","id":"9","title":"Generic/Default vectorization"}},"length":61,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"0":{"0":{"0":{"0":{"df":3,"docs":{"18":{"tf":3.872983346207417},"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"7":{"8":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"7":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"2":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"2":{"2":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"1":{"5":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"2":{"8":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"8":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"1":{"2":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"9":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"9":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"5":{"7":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"6":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"4":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"3":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"1":{"2":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"9":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"6":{"5":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"7":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"1":{"6":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"4":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"2":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"2":{"8":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"3":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"9":{"7":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"6":{"7":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"1":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"0":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"5":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"8":{"8":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"8":{"9":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"9":{"3":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"8":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"5":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"0":{"9":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"5":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"9":{"6":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"6":{"2":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"1":{"0":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"5":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"7":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"7":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"0":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"21":{"tf":2.449489742783178},"27":{"tf":1.0},"28":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}},"1":{".":{"0":{"0":{"0":{"0":{"df":8,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"2":{"tf":1.4142135623730951},"25":{"tf":3.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"/":{"1":{"6":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"0":{".":{"0":{"0":{"0":{"0":{"df":1,"docs":{"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"0":{"df":1,"docs":{"44":{"tf":1.0}}},"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"6":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}},":":{"1":{":":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":30,"docs":{"1":{"tf":3.1622776601683795},"13":{"tf":3.605551275463989},"14":{"tf":2.23606797749979},"15":{"tf":2.6457513110645907},"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"19":{"tf":3.1622776601683795},"2":{"tf":2.449489742783178},"20":{"tf":2.0},"21":{"tf":4.0},"24":{"tf":3.0},"27":{"tf":4.0},"28":{"tf":3.605551275463989},"29":{"tf":3.1622776601683795},"3":{"tf":1.4142135623730951},"30":{"tf":4.242640687119285},"33":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"59":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}},"u":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"0":{"0":{"0":{"df":9,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178},"28":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":4.58257569495584},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"0":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"d":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}},"df":13,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":2.8284271247461903},"18":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"21":{"tf":2.6457513110645907},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"9":{"tf":2.0}},"n":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"x":{"4":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"3":{".":{"0":{"0":{"0":{"0":{"df":7,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}},"4":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"2":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0}}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":21,"docs":{"1":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"19":{"tf":2.0},"2":{"tf":1.4142135623730951},"20":{"tf":2.0},"21":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":2.6457513110645907},"28":{"tf":2.8284271247461903},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"54":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":2.23606797749979},"6":{"tf":1.0},"60":{"tf":2.23606797749979},"9":{"tf":1.0}},"r":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"4":{".":{"0":{"0":{"0":{"0":{"df":5,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{".":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"9":{"tf":1.0}}},"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"df":1,"docs":{"45":{"tf":1.0}}},"df":11,"docs":{"1":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"24":{"tf":2.449489742783178},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":2.23606797749979},"3":{"tf":1.0},"30":{"tf":3.1622776601683795}},"x":{"2":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}},"6":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"7":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"59":{"tf":3.0},"60":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"55":{"tf":1.0}},"x":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"9":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"_":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"c":{"df":3,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951},"58":{"tf":2.0}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"i":{"df":1,"docs":{"60":{"tf":1.0}}},"o":{"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":1,"docs":{"24":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"a":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"k":{".":{"a":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"b":{"df":1,"docs":{"9":{"tf":1.0}},"o":{"df":0,"docs":{},"v":{"df":7,"docs":{"1":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"c":{"c":{"df":2,"docs":{"36":{"tf":1.0},"37":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"2":{"tf":1.0},"25":{"tf":1.0},"5":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"59":{"tf":1.7320508075688772},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"49":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"d":{"d":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"_":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":7,"docs":{"32":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":4,"docs":{"10":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.0},"55":{"tf":1.4142135623730951}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{":":{":":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"f":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"50":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"a":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"\\":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"\\":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":2,"docs":{"54":{"tf":1.7320508075688772},"55":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"=":{"1":{"df":1,"docs":{"43":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"43":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"=":{"0":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"35":{"tf":1.0},"36":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"35":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.0}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"36":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.0}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"1":{",":{"3":{",":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"24":{"tf":1.0}}},"c":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}},"s":{"=":{"1":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"l":{":":{":":{"a":{"d":{"d":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"l":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"r":{"a":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"o":{"c":{"df":3,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":6,"docs":{"12":{"tf":1.7320508075688772},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"24":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"n":{"d":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"11":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"'":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":8,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":2.0},"56":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"24":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}}},"r":{"c":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"(":{"&":{"1":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"a":{"df":0,"docs":{},"y":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"50":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"x":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"y":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":36,"docs":{"0":{"tf":2.449489742783178},"1":{"tf":3.4641016151377544},"12":{"tf":2.8284271247461903},"13":{"tf":2.0},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"2":{"tf":3.0},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.1622776601683795},"24":{"tf":1.4142135623730951},"25":{"tf":2.23606797749979},"26":{"tf":1.0},"27":{"tf":2.0},"28":{"tf":2.0},"29":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":2.23606797749979},"53":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.7320508075688772},"56":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.7320508075688772},"59":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":29,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":2.0},"10":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":2.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"38":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":2.6457513110645907},"50":{"tf":3.4641016151377544},"51":{"tf":4.47213595499958},"52":{"tf":2.0},"53":{"tf":3.0},"54":{"tf":3.872983346207417},"55":{"tf":4.0},"56":{"tf":1.4142135623730951},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":2.23606797749979}},"e":{"'":{"df":8,"docs":{"3":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":3.1622776601683795},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"28":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"13":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"53":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"d":{"df":4,"docs":{"25":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}},"x":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0}}}}},"b":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"13":{"tf":1.0},"54":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"53":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"22":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}},"i":{"c":{"df":3,"docs":{"0":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":8,"docs":{"21":{"tf":1.0},"25":{"tf":2.0},"28":{"tf":2.0},"3":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979},"60":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"40":{"tf":1.0},"50":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"44":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":11,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"25":{"tf":1.4142135623730951},"30":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"a":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":2,"docs":{"0":{"tf":3.0},"1":{"tf":1.0}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"h":{"df":4,"docs":{"19":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"0":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"18":{"tf":1.0},"38":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"58":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"c":{"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":9,"docs":{"3":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"50":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":2.0},"50":{"tf":1.0},"51":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":1.0},"60":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"29":{"tf":1.0},"38":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.4142135623730951}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"56":{"tf":1.0},"8":{"tf":1.0}}}}}},"r":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":4,"docs":{"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"37":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"36":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}},"i":{"d":{"df":1,"docs":{"53":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"53":{"tf":1.7320508075688772},"54":{"tf":2.0},"55":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"b":{"df":0,"docs":{},"j":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":15,"docs":{"21":{"tf":1.4142135623730951},"24":{"tf":1.0},"3":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":2.0}}}},"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"l":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"44":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"21":{"tf":1.7320508075688772},"22":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"3":{"tf":1.0},"39":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"x":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"21":{"tf":1.0},"9":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"0":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}},"n":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{".":{"0":{"df":1,"docs":{"25":{"tf":1.0}},"f":{"3":{"2":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}},"f":{"3":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":4,"docs":{"1":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}},"df":2,"docs":{"1":{"tf":1.7320508075688772},"25":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"2":{"tf":1.0},"7":{"tf":1.0}}}},"m":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0}}}},"x":{"df":0,"docs":{},"t":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},":":{":":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":7,"docs":{"50":{"tf":2.0},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"_":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":6,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"v":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{":":{":":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"3":{"tf":1.0}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"2":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":6,"docs":{"22":{"tf":1.0},"38":{"tf":1.0},"5":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":5,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":15,"docs":{"0":{"tf":1.0},"1":{"tf":2.23606797749979},"22":{"tf":1.7320508075688772},"24":{"tf":1.0},"27":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"1":{"tf":1.0},"40":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"\"":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"!":{"(":{"\"":{".":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"a":{"d":{"d":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"\"":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"r":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"u":{"d":{"a":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"34":{"tf":1.0},"46":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":1.7320508075688772},"50":{"tf":3.0},"51":{"tf":2.6457513110645907},"52":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"/":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.4142135623730951},"53":{"tf":2.449489742783178},"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":7,"docs":{"48":{"tf":1.7320508075688772},"49":{"tf":1.0},"50":{"tf":2.0},"52":{"tf":1.7320508075688772},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}}}}},"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"a":{"df":0,"docs":{},"t":{"a":{"df":10,"docs":{"0":{"tf":2.0},"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":4,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":12,"docs":{"1":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"58":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"0":{"tf":1.0},"33":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"2":{"tf":2.23606797749979}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"c":{"df":23,"docs":{"0":{"tf":1.0},"1":{"tf":2.0},"34":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"36":{"tf":1.7320508075688772},"37":{"tf":2.449489742783178},"38":{"tf":2.0},"4":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":3.0},"5":{"tf":1.0},"50":{"tf":2.0},"51":{"tf":2.449489742783178},"52":{"tf":1.0},"53":{"tf":3.605551275463989},"54":{"tf":1.7320508075688772},"55":{"tf":2.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"(":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":2.0}},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"51":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"[":{"1":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"12":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"51":{"tf":2.0}}},"df":0,"docs":{}},"3":{"df":6,"docs":{"25":{"tf":1.0},"28":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}},"5":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"df":2,"docs":{"19":{"tf":1.0},"21":{"tf":1.0}}},"2":{"df":1,"docs":{"13":{"tf":1.0}}},"3":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{"df":3,"docs":{"1":{"tf":1.4142135623730951},"24":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"2":{"tf":1.4142135623730951},"51":{"tf":1.0}}},"df":7,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":12,"docs":{"12":{"tf":2.449489742783178},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"2":{"tf":2.23606797749979},"20":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"4":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"s":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}},"[":{"0":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"54":{"tf":1.0}}},"2":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"38":{"tf":1.7320508075688772},"40":{"tf":1.7320508075688772},"43":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"40":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"v":{"df":1,"docs":{"58":{"tf":1.0}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}},"df":1,"docs":{"25":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":2.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"w":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":4,"docs":{"15":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"21":{"tf":1.0},"22":{"tf":1.0},"57":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951}}}}}}},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}},"i":{"df":2,"docs":{"0":{"tf":1.0},"22":{"tf":1.0}}}}},"df":3,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"30":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"58":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":8,"docs":{"31":{"tf":1.4142135623730951},"38":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"q":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"17":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"(":{"df":2,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"39":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"t":{"c":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"v":{"a":{"df":0,"docs":{},"l":{"!":{"(":{"a":{"[":{"1":{":":{"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"51":{"tf":1.0}},"u":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.4142135623730951}},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"33":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":23,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"25":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"4":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"29":{"tf":1.0},"33":{"tf":1.0},"54":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"4":{"tf":1.0},"41":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":15,"docs":{"22":{"tf":2.449489742783178},"24":{"tf":1.0},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"44":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.7320508075688772}}}},"t":{"df":1,"docs":{"55":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"m":{"1":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"2":{"tf":1.0},"3":{"tf":1.7320508075688772}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.4142135623730951}}}},"df":1,"docs":{"50":{"tf":1.0}},"n":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":2.0},"50":{"tf":2.449489742783178},"51":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"40":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"33":{"tf":1.0},"39":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"s":{"df":4,"docs":{"20":{"tf":1.0},"21":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"18":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}}},"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"30":{"tf":1.0},"49":{"tf":1.0},"54":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":2,"docs":{"21":{"tf":1.0},"3":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{",":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":6,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772},"36":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"a":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":2,"docs":{"14":{"tf":1.0},"21":{"tf":1.0}}},"b":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.4142135623730951}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"(":{"a":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.4142135623730951},"15":{"tf":2.0}}}},"o":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"n":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":10,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.4142135623730951},"55":{"tf":1.0},"56":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"c":{"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"g":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":2,"docs":{"1":{"tf":1.0},"43":{"tf":1.0}}},"df":2,"docs":{"44":{"tf":1.0},"51":{"tf":2.23606797749979}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"42":{"tf":1.0}},"i":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":35,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"2":{"tf":2.0},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":2.23606797749979},"38":{"tf":2.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.4142135623730951},"49":{"tf":1.4142135623730951},"5":{"tf":1.0},"51":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951},"53":{"tf":1.7320508075688772},"54":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"59":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"r":{"b":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"0":{"tf":1.4142135623730951},"2":{"tf":1.0},"21":{"tf":1.0},"27":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"54":{"tf":1.0}},"n":{"df":6,"docs":{"30":{"tf":1.4142135623730951},"49":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"o":{"df":7,"docs":{"43":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"7":{"tf":1.0}},"e":{"df":2,"docs":{"1":{"tf":1.0},"21":{"tf":1.0}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"57":{"tf":1.0}},"e":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"57":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"d":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"p":{"df":5,"docs":{"24":{"tf":1.0},"27":{"tf":1.4142135623730951},"31":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"0":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"d":{"df":2,"docs":{"57":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"1":{"tf":1.0},"38":{"tf":1.7320508075688772},"5":{"tf":2.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}}}}},"i":{".":{"df":2,"docs":{"15":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":6,"docs":{"48":{"tf":1.0},"49":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"57":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"35":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"r":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"s":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"32":{"tf":1.0},"38":{"tf":1.0}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":5,"docs":{"22":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":2.8284271247461903}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}}}}},"i":{"c":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}}}},"n":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.0},"2":{"tf":1.4142135623730951},"32":{"tf":1.4142135623730951},"49":{"tf":1.0},"53":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"a":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"a":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":6,"docs":{"22":{"tf":2.0},"24":{"tf":1.4142135623730951},"27":{"tf":1.7320508075688772},"28":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"i":{"c":{"df":6,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"25":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"o":{"df":4,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"51":{"tf":1.4142135623730951},"57":{"tf":1.0}},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"21":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}},"t":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"df":0,"docs":{},"g":{"df":2,"docs":{"0":{"tf":2.449489742783178},"6":{"tf":1.0}},"r":{"df":3,"docs":{"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"f":{"a":{"c":{"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"n":{"df":4,"docs":{"53":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}}},"o":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":4,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"a":{":":{":":{"<":{"df":0,"docs":{},"u":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"3":{"tf":2.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{"0":{"df":1,"docs":{"16":{"tf":1.0}}},"1":{"df":2,"docs":{"16":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":5,"docs":{"12":{"tf":1.4142135623730951},"16":{"tf":2.0},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":8,"docs":{"3":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"48":{"tf":1.0},"50":{"tf":3.0},"51":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":3.605551275463989},"9":{"tf":1.0}}}}}},"y":{"df":1,"docs":{"22":{"tf":1.0}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"!":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"<":{"<":{"<":{"1":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"54":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"t":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}}}}},"i":{"b":{"df":1,"docs":{"32":{"tf":1.0}},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"17":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"21":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"o":{"a":{"d":{"df":3,"docs":{"42":{"tf":1.7320508075688772},"50":{"tf":1.0},"54":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"33":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"g":{"1":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"51":{"tf":1.0}}}},"o":{"df":0,"docs":{},"k":{"df":3,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"56":{"tf":1.0}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}},"w":{"df":1,"docs":{"0":{"tf":1.0}}}}},"m":{"a":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":4,"docs":{"22":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"l":{"@":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"n":{"df":8,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"e":{"df":3,"docs":{"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":10,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"df":0,"docs":{},"i":{"df":5,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"12":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}}},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":6,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979},"54":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"x":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}},"x":{"df":1,"docs":{"9":{"tf":1.0}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":4,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":1,"docs":{"50":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"3":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":13,"docs":{"1":{"tf":2.449489742783178},"3":{"tf":1.0},"38":{"tf":1.7320508075688772},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":2.0},"5":{"tf":1.7320508075688772},"50":{"tf":1.4142135623730951},"51":{"tf":3.1622776601683795},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.23606797749979},"55":{"tf":3.0}}},"y":{":":{":":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{":":{":":{"<":{"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"1":{"0":{"*":{"1":{"0":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":8,"docs":{"12":{"tf":1.0},"2":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"x":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"k":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772}},"s":{"(":{"&":{"a":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}},"i":{"df":8,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"25":{"tf":1.0},"28":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":6,"docs":{"22":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.4142135623730951},"33":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"56":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"0":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"58":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"56":{"tf":1.0}},"p":{"df":0,"docs":{},"l":{"df":4,"docs":{"3":{"tf":1.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}},"t":{"df":10,"docs":{"25":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"50":{"tf":2.449489742783178},"51":{"tf":2.23606797749979},"55":{"tf":2.0},"57":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":6,"docs":{"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"43":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":1,"docs":{"21":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":13,"docs":{"0":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"g":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"w":{"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.4142135623730951}},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},":":{":":{"<":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":6,"docs":{"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":10,"docs":{"13":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"58":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":2,"docs":{"50":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"o":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":13,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.6457513110645907},"60":{"tf":2.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}}},"c":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{":":{":":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"&":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"_":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"{":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"v":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"k":{"(":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"m":{"df":1,"docs":{"50":{"tf":1.0}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":3,"docs":{"10":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":9,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.4142135623730951}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"u":{"b":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}},"df":3,"docs":{"58":{"tf":2.23606797749979},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":10,"docs":{"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":2.0},"39":{"tf":1.4142135623730951},"45":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.7320508075688772},"53":{"tf":1.7320508075688772},"54":{"tf":2.449489742783178},"55":{"tf":2.23606797749979}}}},"df":0,"docs":{}},"r":{"df":13,"docs":{"0":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"3":{"tf":2.449489742783178},"50":{"tf":1.0},"51":{"tf":2.0},"54":{"tf":2.449489742783178},"55":{"tf":2.0},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":3.0}}}},"s":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"30":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"x":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"1":{"tf":1.0},"38":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":2.449489742783178},"55":{"tf":1.0},"8":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"56":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"c":{"!":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":2.0},"51":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":5,"docs":{"0":{"tf":2.0},"4":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"42":{"tf":2.449489742783178}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"11":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":11,"docs":{"0":{"tf":1.4142135623730951},"12":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0},"25":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":4,"docs":{"4":{"tf":1.0},"44":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"49":{"tf":1.7320508075688772},"50":{"tf":1.0},"51":{"tf":2.8284271247461903},"53":{"tf":2.449489742783178}}}}}}},"p":{"df":1,"docs":{"55":{"tf":1.0}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":2.0},"21":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"53":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"50":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"d":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"0":{"tf":2.449489742783178}}}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":6,"docs":{"1":{"tf":1.0},"25":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"57":{"tf":1.0},"6":{"tf":1.0}}},"b":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"c":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"1":{"tf":1.0},"2":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"2":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"57":{"tf":1.0}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"\\":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}},"a":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"54":{"tf":1.7320508075688772},"56":{"tf":1.0}},"m":{"df":2,"docs":{"53":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.0},"3":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":3.1622776601683795},"55":{"tf":2.0}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"9":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"1":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"u":{"(":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},":":{":":{"<":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"2":{"df":1,"docs":{"25":{"tf":1.0}}},"5":{"df":5,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"5":{"df":1,"docs":{"27":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.4142135623730951},"3":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"w":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":1,"docs":{"54":{"tf":1.0}},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}},"d":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":4,"docs":{"55":{"tf":1.0},"56":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"22":{"tf":1.4142135623730951},"30":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0},"9":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.4142135623730951},"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"37":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":3,"docs":{"49":{"tf":1.0},"53":{"tf":1.7320508075688772},"55":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"&":{"a":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"57":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"55":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":6,"docs":{"5":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.0},"53":{"tf":1.4142135623730951},"54":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"30":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{")":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"(":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"2":{"tf":1.0},"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.7320508075688772},"4":{"tf":1.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"31":{"tf":1.0},"40":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"'":{"df":1,"docs":{"50":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"51":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"'":{"df":1,"docs":{"59":{"tf":1.0}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"x":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":1,"docs":{"60":{"tf":1.0}}}},"s":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":9,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"29":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}},"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":4,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":4,"docs":{"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"22":{"tf":1.7320508075688772},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"g":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"!":{"(":{"0":{":":{"2":{":":{"1":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{":":{"3":{":":{"1":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772}}}}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"0":{".":{"0":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"df":0,"docs":{},"u":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"24":{"tf":1.7320508075688772},"25":{"tf":1.7320508075688772},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":3,"docs":{"24":{"tf":1.4142135623730951},"27":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"40":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"57":{"tf":1.0}},"e":{"(":{"0":{"df":5,"docs":{"51":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"df":23,"docs":{"22":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.7320508075688772},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"df":10,"docs":{"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.4142135623730951},"21":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":4,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"12":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"6":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"w":{"c":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":4,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"42":{"tf":1.0}},"n":{"df":4,"docs":{"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"0":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"27":{"tf":1.0},"5":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"58":{"tf":1.0}}},"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.7320508075688772},"4":{"tf":1.0},"56":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.7320508075688772}}}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"z":{"df":0,"docs":{},"e":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"21":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":4,"docs":{"16":{"tf":1.0},"29":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}},"i":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"19":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.0}}}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"r":{"c":{"_":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":4,"docs":{"20":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"y":{"df":1,"docs":{"51":{"tf":1.0}}}},"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{":":{":":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{":":{":":{"a":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"48":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":3.872983346207417},"51":{"tf":2.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"50":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"u":{"b":{"df":5,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"58":{"tf":1.0}},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":3,"docs":{"22":{"tf":1.0},"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"h":{"df":8,"docs":{"1":{"tf":1.0},"38":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"m":{"df":1,"docs":{"9":{"tf":1.0}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":7,"docs":{"0":{"tf":1.7320508075688772},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"40":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"49":{"tf":1.4142135623730951},"53":{"tf":1.0},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"0":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"3":{"tf":1.0},"41":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":3,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.4142135623730951}}}}}}}},"t":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"n":{"df":1,"docs":{"9":{"tf":1.0}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"24":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"25":{"tf":1.0}}}}}}},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"40":{"tf":1.0},"42":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{":":{":":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{")":{".":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"d":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"1":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":4,"docs":{"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"56":{"tf":2.23606797749979},"57":{"tf":2.8284271247461903},"58":{"tf":2.449489742783178},"59":{"tf":3.3166247903554},"60":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"u":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"&":{"a":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"a":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"19":{"tf":1.0},"3":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"o":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}},"t":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.0},"20":{"tf":2.0}},"e":{"(":{"&":{"a":{"df":2,"docs":{"20":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"v":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"38":{"tf":1.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"o":{"df":2,"docs":{"24":{"tf":1.0},"53":{"tf":1.0}}}},"x":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"60":{"tf":1.0}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":7,"docs":{"0":{"tf":2.0},"1":{"tf":2.0},"2":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"u":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":3,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"38":{"tf":1.0},"42":{"tf":1.0}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"1":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"s":{"a":{"df":0,"docs":{},"f":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":2.449489742783178},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":2.6457513110645907}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":5,"docs":{"12":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"s":{"df":42,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"16":{"tf":1.4142135623730951},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.0},"23":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":3.1622776601683795},"51":{"tf":3.0},"53":{"tf":1.4142135623730951},"54":{"tf":3.7416573867739413},"55":{"tf":3.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"i":{"df":0,"docs":{},"z":{"df":2,"docs":{"54":{"tf":2.0},"60":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"3":{".":{"4":{"df":4,"docs":{"38":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":6,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"51":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":18,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":2.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":15,"docs":{"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":1.7320508075688772},"36":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"2":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"!":{"[":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"<":{"_":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"55":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.1622776601683795}}}}}},"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":4,"docs":{"38":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"!":{"(":{"a":{"[":{"1":{":":{"3":{":":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"27":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"25":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}},"y":{"df":2,"docs":{"25":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}},"x":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}}},"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"48":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"3":{"tf":1.0},"40":{"tf":1.0}}}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":7,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":8,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"56":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"x":{",":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}},".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979},"9":{"tf":1.0}}},"y":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"43":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772}}}}}}}}}},"breadcrumbs":{"root":{"0":{".":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"0":{"0":{"0":{"0":{"df":3,"docs":{"18":{"tf":3.872983346207417},"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"7":{"8":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"7":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"2":{"1":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"2":{"2":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"1":{"5":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"2":{"8":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"8":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"1":{"2":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"9":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"9":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"5":{"7":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"6":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"6":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"4":{"3":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"3":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"1":{"2":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"5":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"9":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"6":{"5":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"8":{"7":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"1":{"6":{"0":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"9":{"4":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"3":{"2":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"2":{"8":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"3":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"9":{"7":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"6":{"7":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"1":{"4":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"0":{"1":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"0":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"5":{"0":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"8":{"8":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"2":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.0}}},"df":0,"docs":{}},"8":{"9":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"9":{"3":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"7":{"0":{"8":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"5":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{"0":{"9":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"5":{"6":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"9":{"6":{"df":2,"docs":{"29":{"tf":1.7320508075688772},"30":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"0":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"3":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"6":{"2":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"9":{"1":{"0":{"7":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"5":{"9":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"4":{"7":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"3":{"4":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"5":{"5":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"6":{"7":{"5":{"df":2,"docs":{"29":{"tf":1.4142135623730951},"30":{"tf":2.23606797749979}}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{"0":{"6":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"21":{"tf":2.449489742783178},"27":{"tf":1.0},"28":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}},"1":{".":{"0":{"0":{"0":{"0":{"df":8,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"2":{"tf":1.4142135623730951},"25":{"tf":3.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"/":{"1":{"6":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"0":{".":{"0":{"0":{"0":{"0":{"df":1,"docs":{"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"0":{"df":1,"docs":{"44":{"tf":1.0}}},"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"6":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}},":":{"1":{":":{"0":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":30,"docs":{"1":{"tf":3.1622776601683795},"13":{"tf":3.605551275463989},"14":{"tf":2.23606797749979},"15":{"tf":2.6457513110645907},"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"19":{"tf":3.1622776601683795},"2":{"tf":2.449489742783178},"20":{"tf":2.0},"21":{"tf":4.0},"24":{"tf":3.0},"27":{"tf":4.0},"28":{"tf":3.605551275463989},"29":{"tf":3.1622776601683795},"3":{"tf":1.4142135623730951},"30":{"tf":4.242640687119285},"33":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"59":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}},"u":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"0":{"0":{"0":{"df":9,"docs":{"13":{"tf":3.4641016151377544},"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178},"28":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":4.58257569495584},"27":{"tf":1.7320508075688772},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"0":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"d":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}},"df":13,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":2.8284271247461903},"18":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"21":{"tf":2.6457513110645907},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"9":{"tf":2.0}},"n":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"x":{"4":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"3":{".":{"0":{"0":{"0":{"0":{"df":7,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178},"19":{"tf":3.605551275463989},"20":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}},"4":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"2":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0}}},"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":21,"docs":{"1":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"19":{"tf":2.0},"2":{"tf":1.4142135623730951},"20":{"tf":2.0},"21":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":2.6457513110645907},"28":{"tf":2.8284271247461903},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"54":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":2.23606797749979},"6":{"tf":1.0},"60":{"tf":2.23606797749979},"9":{"tf":1.0}},"r":{"d":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"4":{".":{"0":{"0":{"0":{"0":{"df":5,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"5":{".":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"9":{"tf":1.0}}},"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":2.23606797749979},"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"0":{"df":1,"docs":{"45":{"tf":1.0}}},"df":11,"docs":{"1":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"24":{"tf":2.449489742783178},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":2.23606797749979},"3":{"tf":1.0},"30":{"tf":3.1622776601683795}},"x":{"2":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}},"6":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"4":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"7":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"8":{".":{"0":{"0":{"0":{"0":{"df":4,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772},"59":{"tf":3.0},"60":{"tf":3.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"55":{"tf":1.0}},"x":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"9":{".":{"0":{"0":{"0":{"0":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"_":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"c":{"df":3,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951},"58":{"tf":2.0}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"i":{"df":1,"docs":{"60":{"tf":1.0}}},"o":{"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.0}}},"df":1,"docs":{"24":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"a":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"k":{".":{"a":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"b":{"df":1,"docs":{"9":{"tf":1.0}},"o":{"df":0,"docs":{},"v":{"df":7,"docs":{"1":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"c":{"c":{"df":2,"docs":{"36":{"tf":1.0},"37":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"2":{"tf":1.0},"25":{"tf":1.0},"5":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"59":{"tf":1.7320508075688772},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"49":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"d":{"d":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"_":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":7,"docs":{"32":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":4,"docs":{"10":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{":":{":":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"f":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"50":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"0":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"a":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"\\":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"\\":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":2,"docs":{"54":{"tf":1.7320508075688772},"55":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.4142135623730951}},"e":{"=":{"1":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"=":{"1":{"df":1,"docs":{"43":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"43":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"=":{"0":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0}},"e":{"=":{"1":{"df":1,"docs":{"35":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.4142135623730951}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"36":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.4142135623730951}},"e":{"=":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"!":{"(":{"\"":{"a":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"1":{",":{"3":{",":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"24":{"tf":1.0}}},"c":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.4142135623730951}},"s":{"=":{"1":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"l":{":":{":":{"a":{"d":{"d":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":3,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"l":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"r":{"a":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"24":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"o":{"c":{"df":3,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":6,"docs":{"12":{"tf":1.7320508075688772},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"24":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"n":{"d":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"11":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"'":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":8,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.23606797749979},"56":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"24":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}}},"r":{"c":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"(":{"&":{"1":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"a":{"df":0,"docs":{},"y":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"50":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"x":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"y":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}},"df":36,"docs":{"0":{"tf":2.449489742783178},"1":{"tf":3.605551275463989},"12":{"tf":3.0},"13":{"tf":2.0},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":2.449489742783178},"2":{"tf":3.1622776601683795},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.1622776601683795},"24":{"tf":1.7320508075688772},"25":{"tf":2.449489742783178},"26":{"tf":1.4142135623730951},"27":{"tf":2.23606797749979},"28":{"tf":2.23606797749979},"29":{"tf":2.0},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":2.23606797749979},"53":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.7320508075688772},"56":{"tf":2.0},"57":{"tf":1.7320508075688772},"58":{"tf":2.0},"59":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"60":{"tf":2.0},"9":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":29,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":2.0},"10":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":2.23606797749979},"31":{"tf":1.7320508075688772},"32":{"tf":1.0},"38":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":2.0},"49":{"tf":2.6457513110645907},"50":{"tf":3.605551275463989},"51":{"tf":4.58257569495584},"52":{"tf":2.0},"53":{"tf":3.0},"54":{"tf":4.0},"55":{"tf":4.123105625617661},"56":{"tf":1.7320508075688772},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":2.23606797749979}},"e":{"'":{"df":8,"docs":{"3":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":3.1622776601683795},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"28":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":1,"docs":{"25":{"tf":1.0}}}}}},"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"13":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"53":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"d":{"df":4,"docs":{"25":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}},"x":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0}}}}},"b":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"13":{"tf":1.0},"54":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"53":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"22":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}},"i":{"c":{"df":3,"docs":{"0":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":8,"docs":{"21":{"tf":1.0},"25":{"tf":2.0},"28":{"tf":2.0},"3":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979},"60":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"40":{"tf":1.0},"50":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"44":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":11,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"25":{"tf":1.4142135623730951},"30":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"a":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":2,"docs":{"0":{"tf":3.0},"1":{"tf":1.0}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.7320508075688772}}}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"h":{"df":4,"docs":{"19":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"a":{"df":0,"docs":{},"s":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"0":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"18":{"tf":1.0},"38":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"58":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"c":{"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"[":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":9,"docs":{"3":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951},"58":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"50":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"3":{"tf":2.0},"50":{"tf":1.0},"51":{"tf":1.0},"59":{"tf":1.4142135623730951},"6":{"tf":1.0},"60":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"29":{"tf":1.0},"38":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"56":{"tf":1.0},"8":{"tf":1.0}}}}}},"r":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":4,"docs":{"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"37":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"36":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}},"i":{"d":{"df":1,"docs":{"53":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"53":{"tf":1.7320508075688772},"54":{"tf":2.0},"55":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"b":{"df":0,"docs":{},"j":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"22":{"tf":1.0}}}}},"df":15,"docs":{"21":{"tf":1.4142135623730951},"24":{"tf":1.0},"3":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":2.0}}}},"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"l":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"44":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"21":{"tf":2.0},"22":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"3":{"tf":1.0},"39":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"x":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"21":{"tf":1.0},"9":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"0":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}},"n":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{".":{"0":{"df":1,"docs":{"25":{"tf":1.0}},"f":{"3":{"2":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}},"f":{"3":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.4142135623730951}},"f":{"3":{"2":{"df":4,"docs":{"1":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}},"df":2,"docs":{"1":{"tf":1.7320508075688772},"25":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"49":{"tf":1.0},"53":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"2":{"tf":1.0},"7":{"tf":1.0}}}},"m":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0}}}},"x":{"df":0,"docs":{},"t":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},":":{":":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":7,"docs":{"50":{"tf":2.0},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"_":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":6,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"x":{"df":1,"docs":{"54":{"tf":1.0}}}},"v":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{":":{":":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"3":{"tf":1.0}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"2":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":6,"docs":{"22":{"tf":1.0},"38":{"tf":1.0},"5":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":5,"docs":{"0":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":15,"docs":{"0":{"tf":1.0},"1":{"tf":2.449489742783178},"22":{"tf":1.7320508075688772},"24":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.0},"52":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":2.23606797749979},"57":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"1":{"tf":1.0},"40":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"\"":{"\"":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"!":{"(":{"\"":{".":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"a":{"d":{"d":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"\"":{")":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"r":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"u":{"d":{"a":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":7,"docs":{"34":{"tf":1.0},"46":{"tf":1.0},"48":{"tf":2.23606797749979},"49":{"tf":1.7320508075688772},"50":{"tf":3.1622776601683795},"51":{"tf":2.8284271247461903},"52":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"/":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"49":{"tf":1.4142135623730951},"50":{"tf":1.4142135623730951},"53":{"tf":2.449489742783178},"8":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":7,"docs":{"48":{"tf":1.7320508075688772},"49":{"tf":1.0},"50":{"tf":2.23606797749979},"52":{"tf":1.7320508075688772},"53":{"tf":1.4142135623730951},"54":{"tf":2.23606797749979},"55":{"tf":1.0}}}}}}}},"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"a":{"df":0,"docs":{},"t":{"a":{"df":10,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":4,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":1.0},"51":{"tf":1.0},"6":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":12,"docs":{"1":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"58":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"(":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"0":{"tf":1.0},"33":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"2":{"tf":2.23606797749979}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"c":{"df":23,"docs":{"0":{"tf":1.0},"1":{"tf":2.0},"34":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"36":{"tf":1.7320508075688772},"37":{"tf":2.449489742783178},"38":{"tf":2.0},"4":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":3.0},"5":{"tf":1.0},"50":{"tf":2.0},"51":{"tf":2.449489742783178},"52":{"tf":1.0},"53":{"tf":3.605551275463989},"54":{"tf":1.7320508075688772},"55":{"tf":2.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"(":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"0":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":2.0}},"s":{"[":{"0":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"51":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"[":{"1":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"12":{"tf":1.0},"59":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"4":{"!":{"(":{"1":{"0":{"df":1,"docs":{"51":{"tf":2.0}}},"df":0,"docs":{}},"3":{"df":6,"docs":{"25":{"tf":1.0},"28":{"tf":2.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}},"5":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"1":{"df":2,"docs":{"19":{"tf":1.0},"21":{"tf":1.0}}},"2":{"df":1,"docs":{"13":{"tf":1.0}}},"3":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"5":{"df":3,"docs":{"1":{"tf":1.4142135623730951},"24":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"m":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"2":{"tf":1.4142135623730951},"51":{"tf":1.0}}},"df":7,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":12,"docs":{"12":{"tf":2.449489742783178},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"2":{"tf":2.23606797749979},"20":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"4":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"s":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{}}},"[":{"0":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.4142135623730951}}},"1":{"df":1,"docs":{"54":{"tf":1.0}}},"2":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"2":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"38":{"tf":1.7320508075688772},"40":{"tf":1.7320508075688772},"43":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"40":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"v":{"df":1,"docs":{"58":{"tf":1.0}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}},"df":1,"docs":{"25":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":2.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"w":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"e":{"df":3,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":4,"docs":{"15":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"21":{"tf":1.0},"22":{"tf":1.0},"57":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951}}}}}}},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}},"i":{"df":2,"docs":{"0":{"tf":1.0},"22":{"tf":1.0}}}}},"df":3,"docs":{"3":{"tf":1.4142135623730951},"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"50":{"tf":1.0}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"30":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"58":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":8,"docs":{"31":{"tf":1.7320508075688772},"38":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"q":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"17":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"(":{"df":2,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"39":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"t":{"c":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"v":{"a":{"df":0,"docs":{},"l":{"!":{"(":{"a":{"[":{"1":{":":{"2":{":":{"1":{"df":1,"docs":{"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"51":{"tf":1.0}},"u":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.4142135623730951}},"t":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"33":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":23,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"25":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"4":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"29":{"tf":1.0},"33":{"tf":1.0},"54":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"4":{"tf":1.0},"41":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":15,"docs":{"22":{"tf":2.449489742783178},"24":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"29":{"tf":1.0},"30":{"tf":1.0},"44":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":2.23606797749979},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"t":{"df":1,"docs":{"55":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"m":{"1":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"2":{"tf":1.0},"3":{"tf":2.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.7320508075688772}}}},"df":1,"docs":{"50":{"tf":1.0}},"n":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":2.0},"50":{"tf":2.449489742783178},"51":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"40":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"33":{"tf":1.0},"39":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"s":{"df":4,"docs":{"20":{"tf":1.0},"21":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"18":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"38":{"tf":1.0},"8":{"tf":1.0}}}}},"df":1,"docs":{"9":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"22":{"tf":1.4142135623730951},"3":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"30":{"tf":1.0},"49":{"tf":1.0},"54":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":2,"docs":{"21":{"tf":1.0},"3":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{",":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":6,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772},"36":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"a":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":2,"docs":{"14":{"tf":1.0},"21":{"tf":1.0}}},"b":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"12":{"tf":1.0},"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"(":{"a":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979}}}},"o":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"n":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"9":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":10,"docs":{"18":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.4142135623730951},"55":{"tf":1.0},"56":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"c":{"df":4,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"g":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":2,"docs":{"1":{"tf":1.0},"43":{"tf":1.0}}},"df":2,"docs":{"44":{"tf":1.0},"51":{"tf":2.23606797749979}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"42":{"tf":1.0}},"i":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":35,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"2":{"tf":2.0},"20":{"tf":1.0},"21":{"tf":2.0},"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":2.23606797749979},"38":{"tf":2.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.4142135623730951},"49":{"tf":1.4142135623730951},"5":{"tf":1.0},"51":{"tf":1.4142135623730951},"52":{"tf":1.4142135623730951},"53":{"tf":1.7320508075688772},"54":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.4142135623730951},"9":{"tf":3.3166247903554}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"59":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"g":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"r":{"b":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"0":{"tf":1.4142135623730951},"2":{"tf":1.0},"21":{"tf":1.0},"27":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"49":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"54":{"tf":1.0}},"n":{"df":6,"docs":{"30":{"tf":1.4142135623730951},"49":{"tf":1.0},"55":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"o":{"b":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"o":{"df":7,"docs":{"43":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"7":{"tf":1.4142135623730951}},"e":{"df":2,"docs":{"1":{"tf":1.0},"21":{"tf":1.0}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"f":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"57":{"tf":1.0}},"e":{".":{"df":0,"docs":{},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"57":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"d":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"9":{"tf":1.7320508075688772}}}}}},"l":{"df":0,"docs":{},"p":{"df":5,"docs":{"24":{"tf":1.0},"27":{"tf":1.4142135623730951},"31":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.4142135623730951}}}},"n":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"0":{"tf":2.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"d":{"df":2,"docs":{"57":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"1":{"tf":1.0},"38":{"tf":1.7320508075688772},"5":{"tf":2.23606797749979},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}}}}},"i":{".":{"df":2,"docs":{"15":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"3":{"2":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":6,"docs":{"48":{"tf":1.0},"49":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"57":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"1":{"tf":1.0},"54":{"tf":1.0}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"35":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"r":{"df":2,"docs":{"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}},"s":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"32":{"tf":1.0},"38":{"tf":1.0}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":5,"docs":{"22":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":2.8284271247461903}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}}}}},"i":{"c":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}},"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"df":2,"docs":{"51":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}}}}},"n":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"51":{"tf":1.0}}},"x":{"df":1,"docs":{"51":{"tf":1.0}}}},"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.0},"2":{"tf":1.4142135623730951},"32":{"tf":1.4142135623730951},"49":{"tf":1.0},"53":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"(":{"&":{"a":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"(":{"&":{"a":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":6,"docs":{"22":{"tf":2.23606797749979},"24":{"tf":1.4142135623730951},"27":{"tf":1.7320508075688772},"28":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":2.23606797749979}},"e":{"df":0,"docs":{},"r":{":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"i":{"c":{"df":6,"docs":{"1":{"tf":1.0},"2":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772},"30":{"tf":1.7320508075688772}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"25":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"o":{"df":4,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"51":{"tf":1.4142135623730951},"57":{"tf":1.0}},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"(":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"21":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.7320508075688772},"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}},"t":{"df":1,"docs":{"0":{"tf":1.0}},"e":{"df":0,"docs":{},"g":{"df":2,"docs":{"0":{"tf":2.449489742783178},"6":{"tf":1.0}},"r":{"df":3,"docs":{"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"f":{"a":{"c":{"df":3,"docs":{"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"n":{"df":4,"docs":{"53":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.7320508075688772},"52":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"l":{"df":1,"docs":{"0":{"tf":1.0}}},"o":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":4,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"a":{":":{":":{"<":{"df":0,"docs":{},"u":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"3":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"3":{"tf":2.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"(":{"0":{"df":1,"docs":{"16":{"tf":1.0}}},"1":{"df":2,"docs":{"16":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":5,"docs":{"12":{"tf":1.4142135623730951},"16":{"tf":2.23606797749979},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":8,"docs":{"3":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"48":{"tf":1.0},"50":{"tf":3.1622776601683795},"51":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":3.7416573867739413},"9":{"tf":1.0}}}}}},"y":{"df":1,"docs":{"22":{"tf":1.0}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"!":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"<":{"<":{"<":{"1":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"54":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"t":{"'":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.7320508075688772}}}}}},"i":{"b":{"df":1,"docs":{"32":{"tf":1.0}},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"0":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"17":{"tf":1.0},"4":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"21":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"o":{"a":{"d":{"df":3,"docs":{"42":{"tf":1.7320508075688772},"50":{"tf":1.0},"54":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"33":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"k":{"df":4,"docs":{"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.0},"59":{"tf":1.0}}}},"df":0,"docs":{},"g":{"1":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"51":{"tf":1.0}}}},"o":{"df":0,"docs":{},"k":{"df":3,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"56":{"tf":1.0}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}},"w":{"df":1,"docs":{"0":{"tf":1.0}}}}},"m":{"a":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":4,"docs":{"22":{"tf":1.0},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"l":{"@":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"n":{"df":8,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"58":{"tf":1.0}}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"e":{"df":3,"docs":{"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":10,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.7320508075688772},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":1.4142135623730951},"55":{"tf":2.0}}}},"df":0,"docs":{},"i":{"df":5,"docs":{"0":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"21":{"tf":1.0}}}}}}},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":6,"docs":{"50":{"tf":2.6457513110645907},"51":{"tf":2.23606797749979},"54":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"x":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"21":{"tf":1.0}}}}}},"x":{"df":1,"docs":{"9":{"tf":1.0}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":4,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":1,"docs":{"50":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"3":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":13,"docs":{"1":{"tf":2.449489742783178},"3":{"tf":1.0},"38":{"tf":1.7320508075688772},"43":{"tf":1.0},"48":{"tf":1.0},"49":{"tf":2.0},"5":{"tf":2.0},"50":{"tf":1.4142135623730951},"51":{"tf":3.1622776601683795},"52":{"tf":1.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.23606797749979},"55":{"tf":3.0}}},"y":{":":{":":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{":":{":":{"<":{"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"1":{"0":{"*":{"1":{"0":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{"d":{"_":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}},"o":{"df":1,"docs":{"50":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":8,"docs":{"12":{"tf":1.0},"2":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}},"x":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"k":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":2.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}},"i":{"df":8,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"57":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":6,"docs":{"22":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.4142135623730951},"33":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"56":{"tf":1.0},"57":{"tf":1.7320508075688772},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"0":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"58":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"56":{"tf":1.0}},"p":{"df":0,"docs":{},"l":{"df":4,"docs":{"3":{"tf":1.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.7320508075688772},"59":{"tf":1.4142135623730951}}}}}}},"t":{"df":10,"docs":{"25":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"50":{"tf":2.449489742783178},"51":{"tf":2.23606797749979},"55":{"tf":2.0},"57":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":6,"docs":{"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"43":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":1,"docs":{"21":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":13,"docs":{"0":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.4142135623730951},"52":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.7320508075688772}}},"df":0,"docs":{}},"g":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":2.0}}},"w":{"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":1,"docs":{"53":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.4142135623730951}},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},":":{":":{"<":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":6,"docs":{"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":2.23606797749979},"55":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"25":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":10,"docs":{"13":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"50":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"58":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"9":{"tf":1.0}}}}},"df":2,"docs":{"50":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"o":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"_":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":13,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.6457513110645907},"60":{"tf":2.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":2.0},"55":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}}},"c":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{":":{":":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{"(":{"&":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":1,"docs":{"54":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"(":{"a":{"df":0,"docs":{},"f":{"_":{"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"(":{"&":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"w":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"d":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"55":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"_":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"(":{"&":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"{":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"v":{"df":1,"docs":{"54":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.0}}}}}}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"54":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":1,"docs":{"51":{"tf":1.4142135623730951}},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"k":{"(":{"c":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}},"m":{"df":1,"docs":{"50":{"tf":1.0}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}},"df":2,"docs":{"50":{"tf":1.7320508075688772},"51":{"tf":1.4142135623730951}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"0":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":3,"docs":{"10":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":9,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.0},"4":{"tf":1.0},"51":{"tf":1.0},"9":{"tf":1.4142135623730951}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"58":{"tf":1.7320508075688772},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"u":{"b":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":1,"docs":{"53":{"tf":1.0}}}}},"df":3,"docs":{"58":{"tf":2.23606797749979},"59":{"tf":1.7320508075688772},"60":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":10,"docs":{"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":2.0},"39":{"tf":1.4142135623730951},"45":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":2.0},"53":{"tf":1.7320508075688772},"54":{"tf":2.6457513110645907},"55":{"tf":2.449489742783178}}}},"df":0,"docs":{}},"r":{"df":13,"docs":{"0":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"3":{"tf":2.449489742783178},"50":{"tf":1.0},"51":{"tf":2.0},"54":{"tf":2.449489742783178},"55":{"tf":2.0},"58":{"tf":1.0},"59":{"tf":1.0},"6":{"tf":2.0},"9":{"tf":3.0}}}},"s":{".":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"30":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0},"56":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"x":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"1":{"tf":1.0},"38":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"1":{"tf":1.0},"13":{"tf":1.0},"43":{"tf":1.0},"50":{"tf":2.449489742783178},"55":{"tf":1.0},"8":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"56":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":2,"docs":{"51":{"tf":1.4142135623730951},"59":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"c":{"!":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":2.0},"51":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"50":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":5,"docs":{"0":{"tf":2.0},"4":{"tf":1.0},"58":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"51":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"42":{"tf":2.449489742783178}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"11":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":11,"docs":{"0":{"tf":1.4142135623730951},"12":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0},"25":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":4,"docs":{"4":{"tf":1.0},"44":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"49":{"tf":1.7320508075688772},"50":{"tf":1.0},"51":{"tf":2.8284271247461903},"53":{"tf":2.449489742783178}}}}}}},"p":{"df":1,"docs":{"55":{"tf":1.0}},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":2.23606797749979},"21":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"53":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"1":{"tf":1.0},"50":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"d":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"0":{"tf":2.449489742783178}}}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":6,"docs":{"1":{"tf":1.0},"25":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"57":{"tf":1.0},"6":{"tf":1.0}}},"b":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"c":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}}},"d":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"1":{"tf":1.0},"2":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"u":{"b":{"2":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"2":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"57":{"tf":1.0}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"\\":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"57":{"tf":1.0}}}}}}}},"a":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"2":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"49":{"tf":1.0},"50":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"54":{"tf":1.7320508075688772},"56":{"tf":1.0}},"m":{"df":2,"docs":{"53":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.0},"53":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.0},"3":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}},"x":{"df":1,"docs":{"50":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.4142135623730951}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"52":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":3.1622776601683795},"55":{"tf":2.0}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"9":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"55":{"tf":1.4142135623730951}}}},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"1":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"u":{"(":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}},":":{":":{"<":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"3":{"2":{">":{"(":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"4":{"!":{"(":{"2":{"df":1,"docs":{"25":{"tf":1.0}}},"5":{"df":5,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"&":{"[":{"5":{"df":1,"docs":{"27":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.4142135623730951},"3":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"w":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":1,"docs":{"54":{"tf":1.0}},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}},"d":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"59":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":4,"docs":{"55":{"tf":1.0},"56":{"tf":1.0},"58":{"tf":1.4142135623730951},"59":{"tf":1.0}}},"df":0,"docs":{},"l":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"50":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"1":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"22":{"tf":1.4142135623730951},"30":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0},"9":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.4142135623730951},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"51":{"tf":1.0}}}}}}}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"37":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":3,"docs":{"49":{"tf":1.0},"53":{"tf":1.7320508075688772},"55":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"&":{"a":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"57":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"55":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"55":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":6,"docs":{"5":{"tf":1.0},"50":{"tf":1.7320508075688772},"51":{"tf":1.0},"53":{"tf":1.4142135623730951},"54":{"tf":1.7320508075688772},"59":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"51":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"30":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}},"e":{"(":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"g":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"(":{"&":{"a":{"df":2,"docs":{"29":{"tf":1.0},"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{")":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"(":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"30":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":2,"docs":{"2":{"tf":1.0},"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.7320508075688772},"4":{"tf":1.0}},"s":{"(":{"&":{"a":{"df":1,"docs":{"30":{"tf":1.0}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":2,"docs":{"22":{"tf":1.0},"29":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"48":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"0":{"tf":1.0},"31":{"tf":1.0},"40":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"'":{"df":1,"docs":{"50":{"tf":1.0}}},":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"(":{"c":{"df":0,"docs":{},"u":{"d":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"50":{"tf":2.23606797749979},"51":{"tf":2.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"'":{"df":1,"docs":{"59":{"tf":1.0}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}},"x":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":1,"docs":{"60":{"tf":1.0}}}},"s":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":9,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"29":{"tf":1.0},"50":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.0}}}}},"c":{"a":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"2":{"tf":1.0},"54":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":4,"docs":{"1":{"tf":1.0},"43":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":4,"docs":{"1":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"22":{"tf":1.7320508075688772},"57":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}},"m":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"g":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"!":{"(":{"0":{":":{"2":{":":{"1":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{":":{"3":{":":{"1":{"df":2,"docs":{"24":{"tf":1.0},"25":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"(":{"0":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{}},"4":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"27":{"tf":1.7320508075688772},"28":{"tf":1.7320508075688772}}}}}},":":{":":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"0":{".":{"0":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"1":{"df":0,"docs":{},"u":{"3":{"2":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"25":{"tf":1.7320508075688772},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":3,"docs":{"24":{"tf":1.4142135623730951},"27":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"40":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}}}},"t":{"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":7,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"57":{"tf":1.0}},"e":{"(":{"0":{"df":5,"docs":{"51":{"tf":1.0},"57":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"53":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"53":{"tf":1.0}}},"df":0,"docs":{}},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"49":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"29":{"tf":1.4142135623730951}}}}}},"df":23,"docs":{"22":{"tf":1.0},"25":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":2.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"53":{"tf":1.4142135623730951},"58":{"tf":1.0},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"51":{"tf":1.0}}},"r":{"df":10,"docs":{"1":{"tf":1.0},"12":{"tf":1.4142135623730951},"2":{"tf":1.4142135623730951},"21":{"tf":1.0},"4":{"tf":1.0},"49":{"tf":1.0},"51":{"tf":1.0},"53":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"56":{"tf":1.0},"60":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":4,"docs":{"50":{"tf":1.0},"54":{"tf":1.0},"58":{"tf":1.0},"60":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"(":{"&":{"a":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"12":{"tf":1.4142135623730951},"18":{"tf":2.0},"6":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"w":{"c":{"a":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":4,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"19":{"tf":1.0},"42":{"tf":1.0}},"n":{"df":4,"docs":{"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.4142135623730951}}}},"df":1,"docs":{"0":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"27":{"tf":1.0},"5":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"55":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"58":{"tf":1.0}}},"df":2,"docs":{"59":{"tf":1.0},"60":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":2,"docs":{"3":{"tf":1.0},"9":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.7320508075688772},"4":{"tf":1.0},"56":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}},"z":{"df":0,"docs":{},"e":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"50":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}},"m":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"21":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"0":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"(":{"&":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":2,"docs":{"27":{"tf":1.0},"28":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":3,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"54":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"24":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":4,"docs":{"16":{"tf":1.0},"29":{"tf":1.0},"48":{"tf":1.0},"52":{"tf":1.0}},"i":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"19":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"49":{"tf":1.4142135623730951},"53":{"tf":1.0}}}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"r":{"c":{"_":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"]":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"54":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":4,"docs":{"20":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"1":{"tf":1.0},"50":{"tf":1.4142135623730951},"51":{"tf":1.0}}}},"y":{"df":1,"docs":{"51":{"tf":1.0}}}},"d":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{":":{":":{"c":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"51":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{":":{":":{"a":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"59":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"9":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":4,"docs":{"48":{"tf":1.0},"49":{"tf":1.0},"50":{"tf":3.872983346207417},"51":{"tf":2.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"50":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"55":{"tf":1.0}}}}}},"u":{"b":{"df":5,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":1.0},"25":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"58":{"tf":1.0}},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}},"t":{"df":3,"docs":{"22":{"tf":1.0},"29":{"tf":1.0},"9":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"h":{"df":8,"docs":{"1":{"tf":1.0},"38":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"48":{"tf":1.0},"5":{"tf":1.0},"52":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"m":{"df":1,"docs":{"9":{"tf":1.0}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":7,"docs":{"0":{"tf":2.0},"3":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"40":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"49":{"tf":1.4142135623730951},"53":{"tf":1.0},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"(":{"0":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"3":{"tf":1.0},"41":{"tf":1.0},"48":{"tf":1.0},"50":{"tf":1.0},"52":{"tf":1.0},"54":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":3,"docs":{"22":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.4142135623730951}}}}}}}},"t":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"n":{"df":1,"docs":{"9":{"tf":1.0}},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"22":{"tf":1.0},"24":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"25":{"tf":1.0}}}}}}},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"40":{"tf":1.0},"42":{"tf":1.0},"54":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{":":{":":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"(":{")":{".":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"57":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"d":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"1":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":4,"docs":{"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":5,"docs":{"56":{"tf":2.449489742783178},"57":{"tf":3.0},"58":{"tf":2.6457513110645907},"59":{"tf":3.4641016151377544},"60":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"u":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.4142135623730951},"58":{"tf":1.0}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"&":{"a":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"a":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"_":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":2,"docs":{"12":{"tf":1.0},"19":{"tf":2.0}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"19":{"tf":1.0},"3":{"tf":1.0},"38":{"tf":1.0},"51":{"tf":1.0}}}}},"o":{"d":{"df":0,"docs":{},"o":{"df":1,"docs":{"50":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}},"t":{"df":2,"docs":{"3":{"tf":1.0},"6":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.0},"20":{"tf":2.23606797749979}},"e":{"(":{"&":{"a":{"df":2,"docs":{"20":{"tf":1.0},"21":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"i":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"v":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"38":{"tf":1.0},"55":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"59":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"o":{"df":2,"docs":{"24":{"tf":1.0},"53":{"tf":1.0}}}},"x":{".":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"_":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"c":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"60":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"60":{"tf":1.0}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":7,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":2.0},"2":{"tf":1.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"53":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"u":{"1":{"6":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}},"3":{"2":{"df":2,"docs":{"0":{"tf":1.0},"1":{"tf":1.0}}},"df":0,"docs":{}},"6":{"4":{"df":3,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"55":{"tf":1.0}}},"df":0,"docs":{}},"8":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"38":{"tf":1.0},"42":{"tf":1.0}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.4142135623730951}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":3,"docs":{"1":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"50":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"s":{"a":{"df":0,"docs":{},"f":{"df":4,"docs":{"50":{"tf":1.0},"51":{"tf":1.4142135623730951},"54":{"tf":2.449489742783178},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"0":{"tf":2.6457513110645907}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":2,"docs":{"54":{"tf":1.4142135623730951},"55":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":5,"docs":{"12":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}},"s":{"df":42,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"16":{"tf":1.4142135623730951},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.0},"23":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"49":{"tf":1.0},"5":{"tf":1.0},"50":{"tf":3.3166247903554},"51":{"tf":3.0},"53":{"tf":1.4142135623730951},"54":{"tf":3.7416573867739413},"55":{"tf":3.0},"56":{"tf":1.4142135623730951},"58":{"tf":1.4142135623730951},"59":{"tf":1.0},"6":{"tf":1.0},"60":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"38":{"tf":1.0},"51":{"tf":1.0},"55":{"tf":1.0}}}},"i":{"df":0,"docs":{},"z":{"df":2,"docs":{"54":{"tf":2.0},"60":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"3":{".":{"4":{"df":4,"docs":{"38":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":6,"docs":{"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"51":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":18,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":2.0},"2":{"tf":1.4142135623730951},"25":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":15,"docs":{"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":1.7320508075688772},"36":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"2":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"!":{"[":{"0":{".":{"0":{"df":0,"docs":{},"f":{"3":{"2":{"df":1,"docs":{"55":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"a":{"d":{"d":{"df":3,"docs":{"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"<":{"_":{"df":3,"docs":{"58":{"tf":1.4142135623730951},"59":{"tf":1.4142135623730951},"60":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"55":{"tf":1.7320508075688772}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"2":{"tf":1.0},"3":{"tf":1.0},"55":{"tf":1.0},"8":{"tf":2.449489742783178},"9":{"tf":3.3166247903554}}}}}},"df":0,"docs":{},"r":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":4,"docs":{"38":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"!":{"(":{"a":{"[":{"1":{":":{"3":{":":{"1":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"3":{"df":1,"docs":{"24":{"tf":1.0}}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"22":{"tf":1.4142135623730951},"24":{"tf":2.0},"27":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"54":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"50":{"tf":1.0},"51":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":5,"docs":{"25":{"tf":1.0},"48":{"tf":1.0},"51":{"tf":1.0},"52":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"40":{"tf":1.0}}}},"y":{"df":2,"docs":{"25":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"1":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"9":{"tf":1.0}},"x":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}}},"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"40":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"h":{"df":3,"docs":{"48":{"tf":1.0},"52":{"tf":1.0},"55":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"48":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"3":{"tf":1.0},"40":{"tf":1.0}}}}}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{".":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"59":{"tf":1.0}}}}}}},"df":1,"docs":{"59":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":7,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.0},"53":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"50":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.7320508075688772}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"51":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":8,"docs":{"0":{"tf":1.0},"3":{"tf":1.4142135623730951},"48":{"tf":1.0},"52":{"tf":1.0},"56":{"tf":1.4142135623730951},"59":{"tf":2.0},"60":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"x":{",":{"df":0,"docs":{},"i":{"df":1,"docs":{"21":{"tf":1.0}}}},".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":6,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979},"9":{"tf":1.0}}},"y":{".":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"50":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"51":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"50":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"50":{"tf":1.4142135623730951},"51":{"tf":1.7320508075688772},"58":{"tf":2.23606797749979},"59":{"tf":2.23606797749979},"60":{"tf":2.23606797749979}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"51":{"tf":1.0},"55":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"43":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"15":{"tf":1.0},"19":{"tf":1.7320508075688772}}}}}}}}}},"title":{"root":{"a":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"df":0,"docs":{}},"d":{"df":3,"docs":{"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}},"df":0,"docs":{},"f":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"d":{"a":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":1,"docs":{"40":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"_":{"c":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"36":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"x":{"_":{"df":0,"docs":{},"j":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"d":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"32":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"42":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"_":{"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"y":{"df":14,"docs":{"1":{"tf":1.0},"12":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"5":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":7,"docs":{"3":{"tf":1.0},"31":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0},"56":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"b":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"49":{"tf":1.0},"53":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"21":{"tf":1.0},"26":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"1":{"tf":1.0},"24":{"tf":1.0},"27":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"d":{"a":{"df":3,"docs":{"48":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"0":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"21":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"x":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"24":{"tf":1.0},"25":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"50":{"tf":1.0},"51":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"f":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"o":{"df":1,"docs":{"7":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"21":{"tf":1.0}}},"df":0,"docs":{}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"p":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":2,"docs":{"22":{"tf":1.0},"4":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"48":{"tf":1.0},"52":{"tf":1.0}}}}}}}}}}},"j":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"50":{"tf":1.0},"54":{"tf":1.0}}}}}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"12":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"o":{"d":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"57":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"58":{"tf":1.0},"59":{"tf":1.0}}}}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"30":{"tf":1.0}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"l":{"df":3,"docs":{"52":{"tf":1.0},"54":{"tf":1.0},"55":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"1":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"58":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":2,"docs":{"23":{"tf":1.0},"26":{"tf":1.0}}},"t":{"df":1,"docs":{"29":{"tf":1.0}}}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"60":{"tf":1.0}}}}}},"u":{"b":{"df":2,"docs":{"25":{"tf":1.0},"28":{"tf":1.0}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":4,"docs":{"56":{"tf":1.0},"57":{"tf":1.0},"58":{"tf":1.0},"59":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"50":{"tf":1.0},"60":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":2,"docs":{"24":{"tf":1.0},"27":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"3":{"tf":1.0},"59":{"tf":1.0},"60":{"tf":1.0}}}}}}}}}},"pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}} \ No newline at end of file diff --git a/book/theme/book.js b/book/theme/book.js new file mode 100644 index 000000000..ca73ee14d --- /dev/null +++ b/book/theme/book.js @@ -0,0 +1,620 @@ +"use strict"; + +// Fix back button cache problem +window.onunload = function () { }; + +// Global variable, shared between modules +function playpen_text(playpen) { + let code_block = playpen.querySelector("code"); + + if (window.ace && code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + return editor.getValue(); + } else { + return code_block.textContent; + } +} + +(function codeSnippets() { + // Hide Rust code lines prepended with a specific character + var hiding_character = "#"; + + function fetch_with_timeout(url, options, timeout = 6000) { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) + ]); + } + + var playpens = Array.from(document.querySelectorAll(".playpen")); + if (playpens.length > 0) { + fetch_with_timeout("https://play.rust-lang.org/meta/crates", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + }) + .then(response => response.json()) + .then(response => { + // get list of crates available in the rust playground + let playground_crates = response.crates.map(item => item["id"]); + playpens.forEach(block => handle_crate_list_update(block, playground_crates)); + }); + } + + function handle_crate_list_update(playpen_block, playground_crates) { + // update the play buttons after receiving the response + update_play_button(playpen_block, playground_crates); + + // and install on change listener to dynamically update ACE editors + if (window.ace) { + let code_block = playpen_block.querySelector("code"); + if (code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + editor.addEventListener("change", function (e) { + update_play_button(playpen_block, playground_crates); + }); + } + } + } + + // updates the visibility of play button based on `no_run` class and + // used crates vs ones available on http://play.rust-lang.org + function update_play_button(pre_block, playground_crates) { + var play_button = pre_block.querySelector(".play-button"); + + // skip if code is `no_run` + if (pre_block.querySelector('code').classList.contains("no_run")) { + play_button.classList.add("hidden"); + return; + } + + // get list of `extern crate`'s from snippet + var txt = playpen_text(pre_block); + var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; + var snippet_crates = []; + var item; + while (item = re.exec(txt)) { + snippet_crates.push(item[1]); + } + + // check if all used crates are available on play.rust-lang.org + var all_available = snippet_crates.every(function (elem) { + return playground_crates.indexOf(elem) > -1; + }); + + if (all_available) { + play_button.classList.remove("hidden"); + } else { + play_button.classList.add("hidden"); + } + } + + function run_rust_code(code_block) { + var result_block = code_block.querySelector(".result"); + if (!result_block) { + result_block = document.createElement('code'); + result_block.className = 'result hljs language-bash'; + + code_block.append(result_block); + } + + let text = playpen_text(code_block); + let classes = code_block.querySelector('code').classList; + let has_2018 = classes.contains("edition2018"); + let edition = has_2018 ? "2018" : "2015"; + + var params = { + version: "stable", + optimize: "0", + code: text, + edition: edition + }; + + if (text.indexOf("#![feature") !== -1) { + params.version = "nightly"; + } + + result_block.innerText = "Running..."; + + fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + body: JSON.stringify(params) + }) + .then(response => response.json()) + .then(response => result_block.innerText = response.result) + .catch(error => result_block.innerText = "Playground Communication: " + error.message); + } + + // Syntax highlighting Configuration + hljs.configure({ + tabReplace: ' ', // 4 spaces + languages: [], // Languages used for auto-detection + }); + + if (window.ace) { + // language-rust class needs to be removed for editable + // blocks or highlightjs will capture events + Array + .from(document.querySelectorAll('code.editable')) + .forEach(function (block) { block.classList.remove('language-rust'); }); + + Array + .from(document.querySelectorAll('code:not(.editable)')) + .forEach(function (block) { hljs.highlightBlock(block); }); + } else { + Array + .from(document.querySelectorAll('code')) + .forEach(function (block) { hljs.highlightBlock(block); }); + } + + // Adding the hljs class gives code blocks the color css + // even if highlighting doesn't apply + Array + .from(document.querySelectorAll('code')) + .forEach(function (block) { block.classList.add('hljs'); }); + + Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) { + + var code_block = block; + var pre_block = block.parentNode; + // hide lines + var lines = code_block.innerHTML.split("\n"); + var first_non_hidden_line = false; + var lines_hidden = false; + var trimmed_line = ""; + + for (var n = 0; n < lines.length; n++) { + trimmed_line = lines[n].trim(); + if (trimmed_line[0] == hiding_character && trimmed_line[1] != hiding_character) { + if (first_non_hidden_line) { + lines[n] = "" + "\n" + lines[n].replace(/(\s*)# ?/, "$1") + ""; + } + else { + lines[n] = "" + lines[n].replace(/(\s*)# ?/, "$1") + "\n" + ""; + } + lines_hidden = true; + } + else if (first_non_hidden_line) { + lines[n] = "\n" + lines[n]; + } + else { + first_non_hidden_line = true; + } + if (trimmed_line[0] == hiding_character && trimmed_line[1] == hiding_character) { + lines[n] = lines[n].replace("##", "#") + } + } + code_block.innerHTML = lines.join(""); + + // If no lines were hidden, return + if (!lines_hidden) { return; } + + var buttons = document.createElement('div'); + buttons.className = 'buttons'; + buttons.innerHTML = ""; + + // add expand button + pre_block.insertBefore(buttons, pre_block.firstChild); + + pre_block.querySelector('.buttons').addEventListener('click', function (e) { + if (e.target.classList.contains('fa-expand')) { + var lines = pre_block.querySelectorAll('span.hidden'); + + e.target.classList.remove('fa-expand'); + e.target.classList.add('fa-compress'); + e.target.title = 'Hide lines'; + e.target.setAttribute('aria-label', e.target.title); + + Array.from(lines).forEach(function (line) { + line.classList.remove('hidden'); + line.classList.add('unhidden'); + }); + } else if (e.target.classList.contains('fa-compress')) { + var lines = pre_block.querySelectorAll('span.unhidden'); + + e.target.classList.remove('fa-compress'); + e.target.classList.add('fa-expand'); + e.target.title = 'Show hidden lines'; + e.target.setAttribute('aria-label', e.target.title); + + Array.from(lines).forEach(function (line) { + line.classList.remove('unhidden'); + line.classList.add('hidden'); + }); + } + }); + }); + + Array.from(document.querySelectorAll('pre code')).forEach(function (block) { + var pre_block = block.parentNode; + if (!pre_block.classList.contains('playpen')) { + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var clipButton = document.createElement('button'); + clipButton.className = 'fa fa-copy clip-button'; + clipButton.title = 'Copy to clipboard'; + clipButton.setAttribute('aria-label', clipButton.title); + clipButton.innerHTML = ''; + + buttons.insertBefore(clipButton, buttons.firstChild); + } + }); + + // Process playpen code blocks + Array.from(document.querySelectorAll(".playpen")).forEach(function (pre_block) { + // Add play button + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var runCodeButton = document.createElement('button'); + runCodeButton.className = 'fa fa-play play-button'; + runCodeButton.hidden = true; + runCodeButton.title = 'Run this code'; + runCodeButton.setAttribute('aria-label', runCodeButton.title); + + var copyCodeClipboardButton = document.createElement('button'); + copyCodeClipboardButton.className = 'fa fa-copy clip-button'; + copyCodeClipboardButton.innerHTML = ''; + copyCodeClipboardButton.title = 'Copy to clipboard'; + copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); + + buttons.insertBefore(runCodeButton, buttons.firstChild); + buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); + + runCodeButton.addEventListener('click', function (e) { + run_rust_code(pre_block); + }); + + let code_block = pre_block.querySelector("code"); + if (window.ace && code_block.classList.contains("editable")) { + var undoChangesButton = document.createElement('button'); + undoChangesButton.className = 'fa fa-history reset-button'; + undoChangesButton.title = 'Undo changes'; + undoChangesButton.setAttribute('aria-label', undoChangesButton.title); + + buttons.insertBefore(undoChangesButton, buttons.firstChild); + + undoChangesButton.addEventListener('click', function () { + let editor = window.ace.edit(code_block); + editor.setValue(editor.originalCode); + editor.clearSelection(); + }); + } + }); +})(); + +(function themes() { + var html = document.querySelector('html'); + var themeToggleButton = document.getElementById('theme-toggle'); + var themePopup = document.getElementById('theme-list'); + var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + var stylesheets = { + ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), + tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), + highlight: document.querySelector("[href$='highlight.css']"), + }; + + function showThemes() { + themePopup.style.display = 'block'; + themeToggleButton.setAttribute('aria-expanded', true); + themePopup.querySelector("button#" + document.body.className).focus(); + } + + function hideThemes() { + themePopup.style.display = 'none'; + themeToggleButton.setAttribute('aria-expanded', false); + themeToggleButton.focus(); + } + + function set_theme(theme) { + let ace_theme; + + if (theme == 'coal' || theme == 'navy') { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = false; + stylesheets.highlight.disabled = true; + + ace_theme = "ace/theme/tomorrow_night"; + } else if (theme == 'ayu') { + stylesheets.ayuHighlight.disabled = false; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = true; + ace_theme = "ace/theme/tomorrow_night"; + } else { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = false; + ace_theme = "ace/theme/dawn"; + } + + setTimeout(function () { + themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor; + }, 1); + + if (window.ace && window.editors) { + window.editors.forEach(function (editor) { + editor.setTheme(ace_theme); + }); + } + + var previousTheme; + try { previousTheme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (previousTheme === null || previousTheme === undefined) { previousTheme = default_theme; } + + try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } + + document.body.className = theme; + html.classList.remove(previousTheme); + html.classList.add(theme); + } + + // Set theme + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } + if (theme === null || theme === undefined) { theme = default_theme; } + + set_theme(theme); + + themeToggleButton.addEventListener('click', function () { + if (themePopup.style.display === 'block') { + hideThemes(); + } else { + showThemes(); + } + }); + + themePopup.addEventListener('click', function (e) { + var theme = e.target.id || e.target.parentElement.id; + set_theme(theme); + }); + + themePopup.addEventListener('focusout', function(e) { + // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) + if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { + hideThemes(); + } + }); + + // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang-nursery/mdBook/issues/628 + document.addEventListener('click', function(e) { + if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { + hideThemes(); + } + }); + + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (!themePopup.contains(e.target)) { return; } + + switch (e.key) { + case 'Escape': + e.preventDefault(); + hideThemes(); + break; + case 'ArrowUp': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.previousElementSibling) { + li.previousElementSibling.querySelector('button').focus(); + } + break; + case 'ArrowDown': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.nextElementSibling) { + li.nextElementSibling.querySelector('button').focus(); + } + break; + case 'Home': + e.preventDefault(); + themePopup.querySelector('li:first-child button').focus(); + break; + case 'End': + e.preventDefault(); + themePopup.querySelector('li:last-child button').focus(); + break; + } + }); +})(); + +(function sidebar() { + var html = document.querySelector("html"); + var sidebar = document.getElementById("sidebar"); + var sidebarLinks = document.querySelectorAll('#sidebar a'); + var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); + var firstContact = null; + + function showSidebar() { + html.classList.remove('sidebar-hidden') + html.classList.add('sidebar-visible'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', 0); + }); + sidebarToggleButton.setAttribute('aria-expanded', true); + sidebar.setAttribute('aria-hidden', false); + try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { } + } + + function hideSidebar() { + html.classList.remove('sidebar-visible') + html.classList.add('sidebar-hidden'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', -1); + }); + sidebarToggleButton.setAttribute('aria-expanded', false); + sidebar.setAttribute('aria-hidden', true); + try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { } + } + + // Toggle sidebar + sidebarToggleButton.addEventListener('click', function sidebarToggle() { + if (html.classList.contains("sidebar-hidden")) { + showSidebar(); + } else if (html.classList.contains("sidebar-visible")) { + hideSidebar(); + } else { + if (getComputedStyle(sidebar)['transform'] === 'none') { + hideSidebar(); + } else { + showSidebar(); + } + } + }); + + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + html.classList.add('sidebar-resizing'); + } + function resize(e) { + document.documentElement.style.setProperty('--sidebar-width', (e.clientX - sidebar.offsetLeft) + 'px'); + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + html.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + + document.addEventListener('touchstart', function (e) { + firstContact = { + x: e.touches[0].clientX, + time: Date.now() + }; + }, { passive: true }); + + document.addEventListener('touchmove', function (e) { + if (!firstContact) + return; + + var curX = e.touches[0].clientX; + var xDiff = curX - firstContact.x, + tDiff = Date.now() - firstContact.time; + + if (tDiff < 250 && Math.abs(xDiff) >= 150) { + if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) + showSidebar(); + else if (xDiff < 0 && curX < 300) + hideSidebar(); + + firstContact = null; + } + }, { passive: true }); + + // Scroll sidebar to current active section + var activeSection = sidebar.querySelector(".active"); + if (activeSection) { + sidebar.scrollTop = activeSection.offsetTop; + } +})(); + +(function chapterNavigation() { + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (window.search && window.search.hasFocus()) { return; } + + switch (e.key) { + case 'ArrowRight': + e.preventDefault(); + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + break; + case 'ArrowLeft': + e.preventDefault(); + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + break; + } + }); +})(); + +(function clipboard() { + var clipButtons = document.querySelectorAll('.clip-button'); + + function hideTooltip(elem) { + elem.firstChild.innerText = ""; + elem.className = 'fa fa-copy clip-button'; + } + + function showTooltip(elem, msg) { + elem.firstChild.innerText = msg; + elem.className = 'fa fa-copy tooltipped'; + } + + var clipboardSnippets = new ClipboardJS('.clip-button', { + text: function (trigger) { + hideTooltip(trigger); + let playpen = trigger.closest("pre"); + return playpen_text(playpen); + } + }); + + Array.from(clipButtons).forEach(function (clipButton) { + clipButton.addEventListener('mouseout', function (e) { + hideTooltip(e.currentTarget); + }); + }); + + clipboardSnippets.on('success', function (e) { + e.clearSelection(); + showTooltip(e.trigger, "Copied!"); + }); + + clipboardSnippets.on('error', function (e) { + showTooltip(e.trigger, "Clipboard error!"); + }); +})(); + +(function scrollToTop () { + var menuTitle = document.querySelector('.menu-title'); + + menuTitle.addEventListener('click', function () { + document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); + }); +})(); + +(function autoHideMenu() { + var menu = document.getElementById('menu-bar'); + + var previousScrollTop = document.scrollingElement.scrollTop; + + document.addEventListener('scroll', function () { + if (menu.classList.contains('folded') && document.scrollingElement.scrollTop < previousScrollTop) { + menu.classList.remove('folded'); + } else if (!menu.classList.contains('folded') && document.scrollingElement.scrollTop > previousScrollTop) { + menu.classList.add('folded'); + } + + if (!menu.classList.contains('bordered') && document.scrollingElement.scrollTop > 0) { + menu.classList.add('bordered'); + } + + if (menu.classList.contains('bordered') && document.scrollingElement.scrollTop === 0) { + menu.classList.remove('bordered'); + } + + previousScrollTop = document.scrollingElement.scrollTop; + }, { passive: true }); +})(); diff --git a/book/theme/css/chrome.css b/book/theme/css/chrome.css new file mode 100644 index 000000000..94f86f790 --- /dev/null +++ b/book/theme/css/chrome.css @@ -0,0 +1,451 @@ +/* CSS for UI elements (a.k.a. chrome) */ + +@import 'variables.css'; + +::-webkit-scrollbar { + background: var(--bg); +} +::-webkit-scrollbar-thumb { + background: var(--scrollbar); +} + +#searchresults a, +.content a:link, +a:visited, +a > .hljs { + color: var(--links); +} + +/* Menu Bar */ + +#menu-bar { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 101; + margin: auto calc(0px - var(--page-padding)); +} +#menu-bar > #menu-bar-sticky-container { + display: flex; + flex-wrap: wrap; + background-color: var(--bg); + border-bottom-color: var(--bg); + border-bottom-width: 1px; + border-bottom-style: solid; +} +.js #menu-bar > #menu-bar-sticky-container { + transition: transform 0.3s; +} +#menu-bar.bordered > #menu-bar-sticky-container { + border-bottom-color: var(--table-border-color); +} +#menu-bar i, #menu-bar .icon-button { + position: relative; + padding: 0 8px; + z-index: 10; + line-height: 50px; + cursor: pointer; + transition: color 0.5s; +} +@media only screen and (max-width: 420px) { + #menu-bar i, #menu-bar .icon-button { + padding: 0 5px; + } +} + +.icon-button { + border: none; + background: none; + padding: 0; + color: inherit; +} +.icon-button i { + margin: 0; +} + +.right-buttons { + margin: 0 15px; +} +.right-buttons a { + text-decoration: none; +} + +html:not(.sidebar-visible) #menu-bar:not(:hover).folded > #menu-bar-sticky-container { + transform: translateY(-60px); +} + +.left-buttons { + display: flex; + margin: 0 5px; +} +.no-js .left-buttons { + display: none; +} + +.menu-title { + display: inline-block; + font-weight: 200; + font-size: 20px; + line-height: 50px; + text-align: center; + margin: 0; + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.js .menu-title { + cursor: pointer; +} + +.menu-bar, +.menu-bar:visited, +.nav-chapters, +.nav-chapters:visited, +.mobile-nav-chapters, +.mobile-nav-chapters:visited, +.menu-bar .icon-button, +.menu-bar a i { + color: var(--icons); +} + +.menu-bar i:hover, +.menu-bar .icon-button:hover, +.nav-chapters:hover, +.mobile-nav-chapters i:hover { + color: var(--icons-hover); +} + +/* Nav Icons */ + +.nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + + position: fixed; + top: 50px; /* Height of menu-bar */ + bottom: 0; + margin: 0; + max-width: 150px; + min-width: 90px; + + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; + + transition: color 0.5s; +} + +.nav-chapters:hover { text-decoration: none; } + +.nav-wrapper { + margin-top: 50px; + display: none; +} + +.mobile-nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + width: 90px; + border-radius: 5px; + background-color: var(--sidebar-bg); +} + +.previous { + float: left; +} + +.next { + float: right; + right: var(--page-padding); +} + +@media only screen and (max-width: 1080px) { + .nav-wide-wrapper { display: none; } + .nav-wrapper { display: block; } +} + +@media only screen and (max-width: 1380px) { + .sidebar-visible .nav-wide-wrapper { display: none; } + .sidebar-visible .nav-wrapper { display: block; } +} + +/* Inline code */ + +:not(pre) > .hljs { + display: inline-block; + vertical-align: middle; + padding: 0.1em 0.3em; + border-radius: 3px; +} + +:not(pre):not(a) > .hljs { + color: var(--inline-code-color); + overflow-x: initial; +} + +a:hover > .hljs { + text-decoration: underline; +} + +pre { + position: relative; +} +pre > .buttons { + position: absolute; + z-index: 100; + right: 5px; + top: 5px; + + color: var(--sidebar-fg); + cursor: pointer; +} +pre > .buttons :hover { + color: var(--sidebar-active); +} +pre > .buttons i { + margin-left: 8px; +} +pre > .buttons button { + color: inherit; + background: transparent; + border: none; + cursor: inherit; +} +pre > .result { + margin-top: 10px; +} + +/* Search */ + +#searchresults a { + text-decoration: none; +} + +mark { + border-radius: 2px; + padding: 0 3px 1px 3px; + margin: 0 -3px -1px -3px; + background-color: var(--search-mark-bg); + transition: background-color 300ms linear; + cursor: pointer; +} + +mark.fade-out { + background-color: rgba(0,0,0,0) !important; + cursor: auto; +} + +.searchbar-outer { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); +} + +#searchbar { + width: 100%; + margin: 5px auto 0px auto; + padding: 10px 16px; + transition: box-shadow 300ms ease-in-out; + border: 1px solid var(--searchbar-border-color); + border-radius: 3px; + background-color: var(--searchbar-bg); + color: var(--searchbar-fg); +} +#searchbar:focus, +#searchbar.active { + box-shadow: 0 0 3px var(--searchbar-shadow-color); +} + +.searchresults-header { + font-weight: bold; + font-size: 1em; + padding: 18px 0 0 5px; + color: var(--searchresults-header-fg); +} + +.searchresults-outer { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); + border-bottom: 1px dashed var(--searchresults-border-color); +} + +ul#searchresults { + list-style: none; + padding-left: 20px; +} +ul#searchresults li { + margin: 10px 0px; + padding: 2px; + border-radius: 2px; +} +ul#searchresults li.focus { + background-color: var(--searchresults-li-bg); +} +ul#searchresults span.teaser { + display: block; + clear: both; + margin: 5px 0 0 20px; + font-size: 0.8em; +} +ul#searchresults span.teaser em { + font-weight: bold; + font-style: normal; +} + +/* Sidebar */ + +.sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + font-size: 0.875em; + box-sizing: border-box; + -webkit-overflow-scrolling: touch; + overscroll-behavior-y: contain; + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +.sidebar-resizing { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} +.js:not(.sidebar-resizing) .sidebar { + transition: transform 0.3s; /* Animation: slide away */ +} +.sidebar code { + line-height: 2em; +} +.sidebar .sidebar-scrollbox { + overflow-y: auto; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 10px 10px; +} +.sidebar .sidebar-resize-handle { + position: absolute; + cursor: col-resize; + width: 0; + right: 0; + top: 0; + bottom: 0; +} +.js .sidebar .sidebar-resize-handle { + cursor: col-resize; + width: 5px; +} +.sidebar-hidden .sidebar { + transform: translateX(calc(0px - var(--sidebar-width))); +} +.sidebar::-webkit-scrollbar { + background: var(--sidebar-bg); +} +.sidebar::-webkit-scrollbar-thumb { + background: var(--scrollbar); +} + +.sidebar-visible .page-wrapper { + transform: translateX(var(--sidebar-width)); +} +@media only screen and (min-width: 620px) { + .sidebar-visible .page-wrapper { + transform: none; + margin-left: var(--sidebar-width); + } +} + +.chapter { + list-style: none outside none; + padding-left: 0; + line-height: 2.2em; +} +.chapter li { + color: var(--sidebar-non-existant); +} +.chapter li a { + display: block; + padding: 0; + text-decoration: none; + color: var(--sidebar-fg); +} + +.chapter li a:hover { + color: var(--sidebar-active); +} + +.chapter li .active { + color: var(--sidebar-active); +} + +.spacer { + width: 100%; + height: 3px; + margin: 5px 0px; +} +.chapter .spacer { + background-color: var(--sidebar-spacer); +} + +@media (-moz-touch-enabled: 1), (pointer: coarse) { + .chapter li a { padding: 5px 0; } + .spacer { margin: 10px 0; } +} + +.section { + list-style: none outside none; + padding-left: 20px; + line-height: 1.9em; +} + +/* Theme Menu Popup */ + +.theme-popup { + position: absolute; + left: 10px; + top: 50px; + z-index: 1000; + border-radius: 4px; + font-size: 0.7em; + color: var(--fg); + background: var(--theme-popup-bg); + border: 1px solid var(--theme-popup-border); + margin: 0; + padding: 0; + list-style: none; + display: none; +} +.theme-popup .default { + color: var(--icons); +} +.theme-popup .theme { + width: 100%; + border: 0; + margin: 0; + padding: 2px 10px; + line-height: 25px; + white-space: nowrap; + text-align: left; + cursor: pointer; + color: inherit; + background: inherit; + font-size: inherit; +} +.theme-popup .theme:hover { + background-color: var(--theme-hover); +} +.theme-popup .theme:hover:first-child, +.theme-popup .theme:hover:last-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} diff --git a/book/theme/css/general.css b/book/theme/css/general.css new file mode 100644 index 000000000..57d5d7a60 --- /dev/null +++ b/book/theme/css/general.css @@ -0,0 +1,143 @@ +/* Base styles and content styles */ + +@import 'variables.css'; + +html { + font-family: "Open Sans", sans-serif; + color: var(--fg); + background-color: var(--bg); + text-size-adjust: none; +} + +body { + margin: 0; + font-size: 1rem; + overflow-x: hidden; +} + +code { + font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; + font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */ +} + +.left { float: left; } +.right { float: right; } +.hidden { display: none; } +.play-button.hidden { display: none; } + +h2, h3 { margin-top: 2.5em; } +h4, h5 { margin-top: 2em; } + +.header + .header h3, +.header + .header h4, +.header + .header h5 { + margin-top: 1em; +} + +h1 a.header:target::before, +h2 a.header:target::before, +h3 a.header:target::before, +h4 a.header:target::before { + display: inline-block; + content: "»"; + margin-left: -30px; + width: 30px; +} + +.page { + outline: 0; + padding: 0 var(--page-padding); +} +.page-wrapper { + box-sizing: border-box; +} +.js:not(.sidebar-resizing) .page-wrapper { + transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +} + +.content { + overflow-y: auto; + padding: 0 15px; + padding-bottom: 50px; +} +.content main { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); +} +.content a { text-decoration: none; } +.content a:hover { text-decoration: underline; } +.content img { max-width: 100%; } +.content .header:link, +.content .header:visited { + color: var(--fg); +} +.content .header:link, +.content .header:visited:hover { + text-decoration: none; +} + +table { + margin: 0 auto; + border-collapse: collapse; +} +table td { + padding: 3px 20px; + border: 1px var(--table-border-color) solid; +} +table thead { + background: var(--table-header-bg); +} +table thead td { + font-weight: 700; + border: none; +} +table thead tr { + border: 1px var(--table-header-bg) solid; +} +/* Alternate background colors for rows */ +table tbody tr:nth-child(2n) { + background: var(--table-alternate-bg); +} + + +blockquote { + margin: 20px 0; + padding: 0 20px; + color: var(--fg); + background-color: var(--quote-bg); + border-top: .1em solid var(--quote-border); + border-bottom: .1em solid var(--quote-border); +} + + +:not(.footnote-definition) + .footnote-definition, +.footnote-definition + :not(.footnote-definition) { + margin-top: 2em; +} +.footnote-definition { + font-size: 0.9em; + margin: 0.5em 0; +} +.footnote-definition p { + display: inline; +} + +.tooltiptext { + position: absolute; + visibility: hidden; + color: #fff; + background-color: #333; + transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ + left: -8px; /* Half of the width of the icon */ + top: -35px; + font-size: 0.8em; + text-align: center; + border-radius: 6px; + padding: 5px 8px; + margin: 5px; + z-index: 1000; +} +.tooltipped .tooltiptext { + visibility: visible; +} diff --git a/book/theme/css/print.css b/book/theme/css/print.css new file mode 100644 index 000000000..5e690f755 --- /dev/null +++ b/book/theme/css/print.css @@ -0,0 +1,54 @@ + +#sidebar, +#menu-bar, +.nav-chapters, +.mobile-nav-chapters { + display: none; +} + +#page-wrapper.page-wrapper { + transform: none; + margin-left: 0px; + overflow-y: initial; +} + +#content { + max-width: none; + margin: 0; + padding: 0; +} + +.page { + overflow-y: initial; +} + +code { + background-color: #666666; + border-radius: 5px; + + /* Force background to be printed in Chrome */ + -webkit-print-color-adjust: exact; +} + +pre > .buttons { + z-index: 2; +} + +a, a:visited, a:active, a:hover { + color: #4183c4; + text-decoration: none; +} + +h1, h2, h3, h4, h5, h6 { + page-break-inside: avoid; + page-break-after: avoid; +} + +pre, code { + page-break-inside: avoid; + white-space: pre-wrap; +} + +.fa { + display: none !important; +} diff --git a/book/theme/css/variables.css b/book/theme/css/variables.css new file mode 100644 index 000000000..29daa0729 --- /dev/null +++ b/book/theme/css/variables.css @@ -0,0 +1,210 @@ + +/* Globals */ + +:root { + --sidebar-width: 300px; + --page-padding: 15px; + --content-max-width: 750px; +} + +/* Themes */ + +.ayu { + --bg: hsl(210, 25%, 8%); + --fg: #c5c5c5; + + --sidebar-bg: #14191f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #5c6773; + --sidebar-active: #ffb454; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #0096cf; + + --inline-code-color: #ffb454; + + --theme-popup-bg: #14191f; + --theme-popup-border: #5c6773; + --theme-hover: #191f26; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --table-border-color: hsl(210, 25%, 13%); + --table-header-bg: hsl(210, 25%, 28%); + --table-alternate-bg: hsl(210, 25%, 11%); + + --searchbar-border-color: #848484; + --searchbar-bg: #424242; + --searchbar-fg: #fff; + --searchbar-shadow-color: #d4c89f; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #252932; + --search-mark-bg: #e3b171; +} + +.coal { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6;; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; +} + +.light { + --bg: hsl(0, 0%, 100%); + --fg: #333333; + + --sidebar-bg: #fafafa; + --sidebar-fg: #364149; + --sidebar-non-existant: #aaaaaa; + --sidebar-active: #008cff; + --sidebar-spacer: #f4f4f4; + + --scrollbar: #cccccc; + + --icons: #cccccc; + --icons-hover: #333333; + + --links: #4183c4; + + --inline-code-color: #6e6b5e; + + --theme-popup-bg: #fafafa; + --theme-popup-border: #cccccc; + --theme-hover: #e6e6e6; + + --quote-bg: hsl(197, 37%, 96%); + --quote-border: hsl(197, 37%, 91%); + + --table-border-color: hsl(0, 0%, 95%); + --table-header-bg: hsl(0, 0%, 80%); + --table-alternate-bg: hsl(0, 0%, 97%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #e4f2fe; + --search-mark-bg: #a2cff5; +} + +.navy { + --bg: hsl(226, 23%, 11%); + --fg: #bcbdd0; + + --sidebar-bg: #282d3f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505274; + --sidebar-active: #2b79a2; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6;; + + --theme-popup-bg: #161923; + --theme-popup-border: #737480; + --theme-hover: #282e40; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --table-border-color: hsl(226, 23%, 16%); + --table-header-bg: hsl(226, 23%, 31%); + --table-alternate-bg: hsl(226, 23%, 14%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #aeaec6; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #5f5f71; + --searchresults-border-color: #5c5c68; + --searchresults-li-bg: #242430; + --search-mark-bg: #a2cff5; +} + +.rust { + --bg: hsl(60, 9%, 87%); + --fg: #262625; + + --sidebar-bg: #3b2e2a; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505254; + --sidebar-active: #e69f67; + --sidebar-spacer: #45373a; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #262625; + + --links: #2b79a2; + + --inline-code-color: #6e6b5e; + + --theme-popup-bg: #e1e1db; + --theme-popup-border: #b38f6b; + --theme-hover: #99908a; + + --quote-bg: hsl(60, 5%, 75%); + --quote-border: hsl(60, 5%, 70%); + + --table-border-color: hsl(60, 9%, 82%); + --table-header-bg: #b3a497; + --table-alternate-bg: hsl(60, 9%, 84%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #dec2a2; + --search-mark-bg: #e69f67; +} diff --git a/book/theme/favicon.png b/book/theme/favicon.png new file mode 100644 index 000000000..a5b1aa16c Binary files /dev/null and b/book/theme/favicon.png differ diff --git a/book/theme/highlight.css b/book/theme/highlight.css new file mode 100644 index 000000000..ab8c49c68 --- /dev/null +++ b/book/theme/highlight.css @@ -0,0 +1,79 @@ +/* Base16 Atelier Dune Light - Theme */ +/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ +/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ + +/* Atelier-Dune Comment */ +.hljs-comment, +.hljs-quote { + color: #AAA; +} + +/* Atelier-Dune Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d73737; +} + +/* Atelier-Dune Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b65611; +} + +/* Atelier-Dune Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #60ac39; +} + +/* Atelier-Dune Blue */ +.hljs-title, +.hljs-section { + color: #6684e1; +} + +/* Atelier-Dune Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b854d4; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f1f1f1; + color: #6e6b5e; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #22863a; + background-color: #f0fff4; +} + +.hljs-deletion { + color: #b31d28; + background-color: #ffeef0; +} diff --git a/book/theme/highlight.js b/book/theme/highlight.js new file mode 100644 index 000000000..a3c761178 --- /dev/null +++ b/book/theme/highlight.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.15.8 | BSD3 License | git.io/hljslicense */ +!function(e){var t="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):t&&(t.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return t.hljs}))}(function(n){var m=[],o=Object.keys,g={},u={},t=/^(no-?highlight|plain|text)$/i,v=/\blang(?:uage)?-([\w-]+)\b/i,s=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},h="",w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function x(e){return e.replace(/&/g,"&").replace(//g,">")}function b(e){return e.nodeName.toLowerCase()}function N(e,t){var s=e&&e.exec(t);return s&&0===s.index}function f(e){return t.test(e)}function p(e){var t,s={},r=Array.prototype.slice.call(arguments,1);for(t in e)s[t]=e[t];return r.forEach(function(e){for(t in e)s[t]=e[t]}),s}function _(e){var n=[];return function e(t,s){for(var r=t.firstChild;r;r=r.nextSibling)3===r.nodeType?s+=r.nodeValue.length:1===r.nodeType&&(n.push({event:"start",offset:s,node:r}),s=e(r,s),b(r).match(/br|hr|img|input/)||n.push({event:"stop",offset:s,node:r}));return s}(e,0),n}function a(e){if(r&&!e.langApiRestored){for(var t in e.langApiRestored=!0,r)e[t]&&(e[r[t]]=e[t]);(e.c||[]).concat(e.v||[]).forEach(a)}}function q(i){function d(e){return e&&e.source||e}function c(e,t){return new RegExp(d(e),"m"+(i.cI?"i":"")+(t?"g":""))}!function t(s,e){if(!s.compiled){if(s.compiled=!0,s.k=s.k||s.bK,s.k){var r={},n=function(s,e){i.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var t=e.split("|");r[t[0]]=[s,t[1]?Number(t[1]):1]})};"string"==typeof s.k?n("keyword",s.k):o(s.k).forEach(function(e){n(e,s.k[e])}),s.k=r}s.lR=c(s.l||/\w+/,!0),e&&(s.bK&&(s.b="\\b("+s.bK.split(" ").join("|")+")\\b"),s.b||(s.b=/\B|\b/),s.bR=c(s.b),s.endSameAsBegin&&(s.e=s.b),s.e||s.eW||(s.e=/\B|\b/),s.e&&(s.eR=c(s.e)),s.tE=d(s.e)||"",s.eW&&e.tE&&(s.tE+=(s.e?"|":"")+e.tE)),s.i&&(s.iR=c(s.i)),null==s.r&&(s.r=1),s.c||(s.c=[]),s.c=Array.prototype.concat.apply([],s.c.map(function(e){return(t="self"===e?s:e).v&&!t.cached_variants&&(t.cached_variants=t.v.map(function(e){return p(t,{v:null},e)})),t.cached_variants||t.eW&&[p(t)]||[t];var t})),s.c.forEach(function(e){t(e,s)}),s.starts&&t(s.starts,e);var a=s.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([s.tE,s.i]).map(d).filter(Boolean);s.t=a.length?c(function(e,t){for(var s=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,n="",a=0;a')+t+(s?"":h):t}function d(){u+=null!=m.sL?function(){var e="string"==typeof m.sL;if(e&&!g[m.sL])return x(v);var t=e?y(m.sL,v,!0,a[m.sL]):E(v,m.sL.length?m.sL:void 0);return 0")+'"');return v+=t,t.length||1}var l=C(e);if(!l)throw new Error('Unknown language: "'+e+'"');q(l);var n,m=s||l,a={},u="";for(n=m;n!==l;n=n.parent)n.cN&&(u=o(n.cN,"",!0)+u);var v="",b=0;try{for(var i,f,_=0;m.t.lastIndex=_,i=m.t.exec(t);)f=r(t.substring(_,i.index),i[0]),_=i.index+f;for(r(t.substr(_)),n=m;n.parent;n=n.parent)n.cN&&(u+=h);return{r:b,value:u,language:e,top:m}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:x(t)};throw e}}function E(s,e){e=e||w.languages||o(g);var r={r:0,value:x(s)},n=r;return e.filter(C).filter(d).forEach(function(e){var t=y(e,s,!1);t.language=e,t.r>n.r&&(n=t),t.r>r.r&&(n=r,r=t)}),n.language&&(r.second_best=n),r}function k(e){return w.tabReplace||w.useBR?e.replace(s,function(e,t){return w.useBR&&"\n"===e?"
":w.tabReplace?t.replace(/\t/g,w.tabReplace):""}):e}function i(e){var t,s,r,n,a,i,c,o,d,p,l=function(e){var t,s,r,n,a=e.className+" ";if(a+=e.parentNode?e.parentNode.className:"",s=v.exec(a))return C(s[1])?s[1]:"no-highlight";for(t=0,r=(a=a.split(/\s+/)).length;t/g,"\n"):t=e,a=t.textContent,r=l?y(l,a,!0):E(a),(s=_(t)).length&&((n=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=function(e,t,s){var r=0,n="",a=[];function i(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function o(e){n+=""}function d(e){("start"===e.event?c:o)(e.node)}for(;e.length||t.length;){var p=i();if(n+=x(s.substring(r,p[0].offset)),r=p[0].offset,p===e){for(a.reverse().forEach(o);d(p.splice(0,1)[0]),(p=i())===e&&p.length&&p[0].offset===r;);a.reverse().forEach(c)}else"start"===p[0].event?a.push(p[0].node):a.pop(),d(p.splice(0,1)[0])}return n+x(s.substr(r))}(s,_(n),a)),r.value=k(r.value),e.innerHTML=r.value,e.className=(i=e.className,c=l,o=r.language,d=c?u[c]:o,p=[i.trim()],i.match(/\bhljs\b/)||p.push("hljs"),-1===i.indexOf(d)&&p.push(d),p.join(" ").trim()),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function c(){if(!c.called){c.called=!0;var e=document.querySelectorAll("pre code");m.forEach.call(e,i)}}function C(e){return e=(e||"").toLowerCase(),g[e]||g[u[e]]}function d(e){var t=C(e);return t&&!t.disableAutodetect}return n.highlight=y,n.highlightAuto=E,n.fixMarkup=k,n.highlightBlock=i,n.configure=function(e){w=p(w,e)},n.initHighlighting=c,n.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",c,!1),addEventListener("load",c,!1)},n.registerLanguage=function(t,e){var s=g[t]=e(n);a(s),s.aliases&&s.aliases.forEach(function(e){u[e]=t})},n.listLanguages=function(){return o(g)},n.getLanguage=C,n.autoDetection=d,n.inherit=p,n.IR=n.IDENT_RE="[a-zA-Z]\\w*",n.UIR=n.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",n.NR=n.NUMBER_RE="\\b\\d+(\\.\\d+)?",n.CNR=n.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",n.BNR=n.BINARY_NUMBER_RE="\\b(0b[01]+)",n.RSR=n.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",n.BE=n.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},n.ASM=n.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[n.BE]},n.QSM=n.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[n.BE]},n.PWM=n.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},n.C=n.COMMENT=function(e,t,s){var r=n.inherit({cN:"comment",b:e,e:t,c:[]},s||{});return r.c.push(n.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},n.CLCM=n.C_LINE_COMMENT_MODE=n.C("//","$"),n.CBCM=n.C_BLOCK_COMMENT_MODE=n.C("/\\*","\\*/"),n.HCM=n.HASH_COMMENT_MODE=n.C("#","$"),n.NM=n.NUMBER_MODE={cN:"number",b:n.NR,r:0},n.CNM=n.C_NUMBER_MODE={cN:"number",b:n.CNR,r:0},n.BNM=n.BINARY_NUMBER_MODE={cN:"number",b:n.BNR,r:0},n.CSSNM=n.CSS_NUMBER_MODE={cN:"number",b:n.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},n.RM=n.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[n.BE,{b:/\[/,e:/\]/,r:0,c:[n.BE]}]},n.TM=n.TITLE_MODE={cN:"title",b:n.IR,r:0},n.UTM=n.UNDERSCORE_TITLE_MODE={cN:"title",b:n.UIR,r:0},n.METHOD_GUARD={b:"\\.\\s*"+n.UIR,r:0},n.registerLanguage("apache",function(e){var t={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",t]},t,e.QSM]}}],i:/\S/}}),n.registerLanguage("armasm",function(e){return{cI:!0,aliases:["arm"],l:"\\.?"+e.IR,k:{meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},c:[{cN:"keyword",b:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?",e:"\\s"},e.C("[;@]","$",{r:0}),e.CBCM,e.QSM,{cN:"string",b:"'",e:"[^\\\\]'",r:0},{cN:"title",b:"\\|",e:"\\|",i:"\\n",r:0},{cN:"number",v:[{b:"[#$=]?0x[0-9a-f]+"},{b:"[#$=]?0b[01]+"},{b:"[#$=]\\d+"},{b:"\\b\\d+"}],r:0},{cN:"symbol",v:[{b:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{b:"^\\s*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{b:"[=#]\\w+"}],r:0}]}}),n.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,{cN:"string",b:/'/,e:/'/},t]}}),n.registerLanguage("coffeescript",function(e){var t={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},s="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:t},n=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+s},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=n;var a=e.inherit(e.TM,{b:s}),i="(\\(.*\\))?\\s*\\B[-=]>",c={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:t,c:["self"].concat(n)}]};return{aliases:["coffee","cson","iced"],k:t,i:/\/\*/,c:n.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+s+"\\s*=\\s*"+i,e:"[-=]>",rB:!0,c:[a,c]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:i,e:"[-=]>",rB:!0,c:[c]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[a]},a]},{b:s+":",e:":",rB:!0,rE:!0,r:0}])}}),n.registerLanguage("cpp",function(e){var t={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},s={cN:"string",v:[{b:'(u8?|U|L)?"',e:'"',i:"\\n",c:[e.BE]},{b:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\((?:.|\n)*?\)\1"/},{b:"'\\\\?.",e:"'",i:"."}]},r={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},n={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},e.inherit(s,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},e.CLCM,e.CBCM]},a=e.IR+"\\s*\\(",i={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},c=[t,e.CLCM,e.CBCM,r,s];return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],k:i,i:"",k:i,c:["self",t]},{b:e.IR+"::",k:i},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:i,c:c.concat([{b:/\(/,e:/\)/,k:i,c:c.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+e.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:i,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:i,r:0,c:[e.CLCM,e.CBCM,s,r,t,{b:/\(/,e:/\)/,k:i,r:0,c:["self",e.CLCM,e.CBCM,s,r,t]}]},e.CLCM,e.CBCM,n]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b://,c:["self"]},e.TM]}]),exports:{preprocessor:n,strings:s,k:i}}}),n.registerLanguage("cs",function(e){var t={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long nameof object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},r={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},n=e.inherit(r,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:t},i=e.inherit(a,{i:/\n/}),c={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,i]},o={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},d=e.inherit(o,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},i]});a.c=[o,c,r,e.ASM,e.QSM,s,e.CBCM],i.c=[d,c,n,e.ASM,e.QSM,s,e.inherit(e.CBCM,{i:/\n/})];var p={v:[o,c,r,e.ASM,e.QSM]},l=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp","c#"],k:t,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:"\x3c!--|--\x3e"},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},p,s,{bK:"class interface",e:/[{;=]/,i:/[^\s:,]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{cN:"meta",b:"^\\s*\\[",eB:!0,e:"\\]",eE:!0,c:[{cN:"meta-string",b:/"/,e:/"/}]},{bK:"new return throw await else",r:0},{cN:"function",b:"("+l+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/\s*[{;=]/,eE:!0,k:t,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,r:0,c:[p,s,e.CBCM]},e.CLCM,e.CBCM]}]}}),n.registerLanguage("css",function(e){var t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:"[a-zA-Z-][a-zA-Z0-9_-]*",r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}}),n.registerLanguage("d",function(e){var t="(0|[1-9][\\d_]*)",s="("+t+"|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",r="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",n={cN:"number",b:"\\b"+s+"(L|u|U|Lu|LU|uL|UL)?",r:0},a={cN:"number",b:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+s+"(i|[fF]i|Li))",r:0},i={cN:"string",b:"'("+r+"|.)",e:"'",i:"."},c={cN:"string",b:'"',c:[{b:r,r:0}],e:'"[cwd]?'},o=e.C("\\/\\+","\\+\\/",{c:["self"],r:10});return{l:e.UIR,k:{keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},c:[e.CLCM,e.CBCM,o,{cN:"string",b:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',r:10},c,{cN:"string",b:'[rq]"',e:'"[cwd]?',r:5},{cN:"string",b:"`",e:"`[cwd]?"},{cN:"string",b:'q"\\{',e:'\\}"'},a,n,i,{cN:"meta",b:"^#!",e:"$",r:5},{cN:"meta",b:"#(line)",e:"$",r:5},{cN:"keyword",b:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}),n.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}}),n.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},e.C("\x3c!--","--\x3e",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},e.inherit(e.ASM,{i:null,cN:null,c:null,skip:!0}),e.inherit(e.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}}),n.registerLanguage("handlebars",function(e){var t={"builtin-name":"each in with if else unless bindattr action collection debugger log outlet template unbound view yield"};return{aliases:["hbs","html.hbs","html.handlebars"],cI:!0,sL:"xml",c:[e.C("{{!(--)?","(--)?}}"),{cN:"template-tag",b:/\{\{[#\/]/,e:/\}\}/,c:[{cN:"name",b:/[a-zA-Z\.-]+/,k:t,starts:{eW:!0,r:0,c:[e.QSM]}}]},{cN:"template-variable",b:/\{\{/,e:/\}\}/,k:t}]}}),n.registerLanguage("haskell",function(e){var t={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},s={cN:"meta",b:"{-#",e:"#-}"},r={cN:"meta",b:"^#",e:"$"},n={cN:"type",b:"\\b[A-Z][\\w']*",r:0},a={b:"\\(",e:"\\)",i:'"',c:[s,r,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),t]};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[a,t],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[a,t],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[n,a,t]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[s,n,a,{b:"{",e:"}",c:a.c},t]},{bK:"default",e:"$",c:[n,a,t]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,t]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[n,e.QSM,t]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},s,r,e.QSM,e.CNM,n,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),t,{b:"->|<-"}]}}),n.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}),n.registerLanguage("ini",function(e){var t={cN:"string",c:[e.BE],v:[{b:"'''",e:"'''",r:10},{b:'"""',e:'"""',r:10},{b:'"',e:'"'},{b:"'",e:"'"}]};return{aliases:["toml"],cI:!0,i:/\S/,c:[e.C(";","$"),e.HCM,{cN:"section",b:/^\s*\[+/,e:/\]+/},{b:/^[a-z0-9\[\]_\.-]+\s*=\s*/,e:"$",rB:!0,c:[{cN:"attr",b:/[a-z0-9\[\]_\.-]+/},{b:/=/,eW:!0,r:0,c:[e.C(";","$"),e.HCM,{cN:"literal",b:/\bon|off|true|false|yes|no\b/},{cN:"variable",v:[{b:/\$[\w\d"][\w\d_]*/},{b:/\$\{(.*?)}/}]},t,{cN:"number",b:/([\+\-]+)?[\d]+_[\d_]+/},e.NM]}]}]}}),n.registerLanguage("java",function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s={cN:"number",b:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",r:0};return{aliases:["jsp"],k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},s,{cN:"meta",b:"@[A-Za-z]+"}]}}),n.registerLanguage("javascript",function(e){var t="[A-Za-z$_][0-9A-Za-z$_]*",s={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},r={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:s,c:[]},a={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,a,r,e.RM];var i=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:s,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,a,e.CLCM,e.CBCM,r,{b:/[{,]\s*/,r:0,c:[{b:t+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:t,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+t+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:t},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:s,c:i}]}]},{cN:"",b:/\s/,e:/\s*/,skip:!0},{b://,sL:"xml",c:[{b:/<[A-Za-z0-9\\._:-]+\s*\/>/,skip:!0},{b:/<[A-Za-z0-9\\._:-]+/,e:/(\/[A-Za-z0-9\\._:-]+|[A-Za-z0-9\\._:-]+\/)>/,skip:!0,c:[{b:/<[A-Za-z0-9\\._:-]+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:t}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:i}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor get set",e:/\{/,eE:!0}],i:/#(?!!)/}}),n.registerLanguage("json",function(e){var t={literal:"true false null"},s=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:s,k:t},n={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},a={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return s.splice(s.length,0,n,a),{c:s,k:t,i:"\\S"}}),n.registerLanguage("julia",function(e){var t={keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},s="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",r={l:s,k:t,i:/<\//},n={cN:"subst",b:/\$\(/,e:/\)/,k:t},a={cN:"variable",b:"\\$"+s},i={cN:"string",c:[e.BE,n,a],v:[{b:/\w*"""/,e:/"""\w*/,r:10},{b:/\w*"/,e:/"\w*/}]},c={cN:"string",c:[e.BE,n,a],b:"`",e:"`"},o={cN:"meta",b:"@"+s};return r.c=[{cN:"number",b:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,r:0},{cN:"string",b:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,c,o,{cN:"comment",v:[{b:"#=",e:"=#",r:10},{b:"#",e:"$"}]},e.HCM,{cN:"keyword",b:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{b:/<:/}],n.c=r.c,r}),n.registerLanguage("makefile",function(e){var t={cN:"variable",v:[{b:"\\$\\("+e.UIR+"\\)",c:[e.BE]},{b:/\$[@%",sL:"xml",r:0},{cN:"bullet",b:"^\\s*([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}}),n.registerLanguage("nginx",function(e){var t={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+e.UIR}]},s={eW:!0,l:"[a-z/_]+",k:{literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[e.HCM,{cN:"string",c:[e.BE,t],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{b:"([a-z]+):/",e:"\\s",eW:!0,eE:!0,c:[t]},{cN:"regexp",c:[e.BE,t],v:[{b:"\\s\\^",e:"\\s|{|;",rE:!0},{b:"~\\*?\\s+",e:"\\s|{|;",rE:!0},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},t]};return{aliases:["nginxconf"],c:[e.HCM,{b:e.UIR+"\\s+{",rB:!0,e:"{",c:[{cN:"section",b:e.UIR}],r:0},{b:e.UIR+"\\s",e:";|{",rB:!0,c:[{cN:"attribute",b:e.UIR,starts:s}],r:0}],i:"[^\\s\\}]"}}),n.registerLanguage("objectivec",function(e){var t=/[a-zA-Z@][a-zA-Z0-9_]*/,s="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:{keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},l:t,i:""}]}]},{cN:"class",b:"("+s.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:s,l:t,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}}),n.registerLanguage("perl",function(e){var t="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",s={cN:"subst",b:"[$@]\\{",e:"\\}",k:t},r={b:"->{",e:"}"},n={v:[{b:/\$\d/},{b:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{b:/[\$%@][^\s\w{]/,r:0}]},a=[e.BE,s,n],i=[n,e.HCM,e.C("^\\=\\w","\\=cut",{eW:!0}),r,{cN:"string",c:a,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[e.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[e.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"function",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",eE:!0,r:5,c:[e.TM]},{b:"-\\w\\b",r:0},{b:"^__DATA__$",e:"^__END__$",sL:"mojolicious",c:[{b:"^@@.*",e:"$",cN:"comment"}]}];return s.c=i,{aliases:["pl","pm"],l:/[\w\.]+/,k:t,c:r.c=i}}),n.registerLanguage("php",function(e){var t={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},s={cN:"meta",b:/<\?(php)?|\?>/},r={cN:"string",c:[e.BE,s],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},n={v:[e.BNM,e.CNM]};return{aliases:["php","php3","php4","php5","php6","php7"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.HCM,e.C("//","$",{c:[s]}),e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"}]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},s,{cN:"keyword",b:/\$this\b/},t,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",t,e.CBCM,r,n]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},r,n]}}),n.registerLanguage("properties",function(e){var t="[ \\t\\f]*",s="("+t+"[:=]"+t+"|[ \\t\\f]+)",r="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",n="([^\\\\:= \\t\\f\\n]|\\\\.)+",a={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[e.C("^\\s*[!#]","$"),{b:r+s,rB:!0,c:[{cN:"attr",b:r,endsParent:!0,r:0}],starts:a},{b:n+s,rB:!0,r:0,c:[{cN:"meta",b:n,endsParent:!0,r:0}],starts:a},{cN:"attr",r:0,b:n+t+"$"}]}}),n.registerLanguage("python",function(e){var t={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},s={cN:"meta",b:/^(>>>|\.\.\.) /},r={cN:"subst",b:/\{/,e:/\}/,k:t,i:/#/},n={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[e.BE,s],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[e.BE,s],r:10},{b:/(fr|rf|f)'''/,e:/'''/,c:[e.BE,s,r]},{b:/(fr|rf|f)"""/,e:/"""/,c:[e.BE,s,r]},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},{b:/(fr|rf|f)'/,e:/'/,c:[e.BE,r]},{b:/(fr|rf|f)"/,e:/"/,c:[e.BE,r]},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},i={cN:"params",b:/\(/,e:/\)/,c:["self",s,a,n]};return r.c=[n,a,s],{aliases:["py","gyp","ipython"],k:t,i:/(<\/|->|\?)|=>/,c:[s,a,n,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,i,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}}),n.registerLanguage("ruby",function(e){var t="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",s={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},r={cN:"doctag",b:"@[A-Za-z]+"},n={b:"#<",e:">"},a=[e.C("#","$",{c:[r]}),e.C("^\\=begin","^\\=end",{c:[r],r:10}),e.C("^__END__","\\n$")],i={cN:"subst",b:"#\\{",e:"}",k:s},c={cN:"string",c:[e.BE,i],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},o={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:s},d=[c,n,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(a)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:t}),o].concat(a)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[c,{b:t}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:s},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[n,{cN:"regexp",c:[e.BE,i],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(a),r:0}].concat(a);i.c=d;var p=[{b:/^\s*=>/,starts:{e:"$",c:o.c=d}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:s,i:/\/\*/,c:a.concat(p).concat(d)}}),n.registerLanguage("rust",function(e){var t="([ui](8|16|32|64|128|size)|f(32|64))?",s="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],k:{keyword:"alignof as be box break const continue crate do else enum extern false fn for if impl in let loop match mod mut offsetof once priv proc pub pure ref return self Self sizeof static struct super trait true type typeof unsafe unsized use virtual while where yield move default",literal:"true false Some None Ok Err",built_in:s},l:e.IR+"!?",i:""}]}}),n.registerLanguage("scala",function(e){var t={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"},{b:"\\${",e:"}"}]},s={cN:"string",v:[{b:'"',e:'"',i:"\\n",c:[e.BE]},{b:'"""',e:'"""',r:10},{b:'[a-z]+"',e:'"',i:"\\n",c:[e.BE,t]},{cN:"string",b:'[a-z]+"""',e:'"""',c:[t],r:10}]},r={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},n={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},a={cN:"class",bK:"class object trait type",e:/[:={\[\n;]/,eE:!0,c:[{bK:"extends with",r:10},{b:/\[/,e:/\]/,eB:!0,eE:!0,r:0,c:[r]},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,r:0,c:[r]},n]},i={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[n]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,s,{cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},r,i,a,e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}}),n.registerLanguage("shell",function(e){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}}),n.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}}),n.registerLanguage("swift",function(e){var t={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},s=e.C("/\\*","\\*/",{c:["self"]}),r={cN:"subst",b:/\\\(/,e:"\\)",k:t,c:[]},n={cN:"string",c:[e.BE,r],v:[{b:/"""/,e:/"""/},{b:/"/,e:/"/}]},a={cN:"number",b:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",r:0};return r.c=[a],{k:t,c:[n,e.CLCM,s,{cN:"type",b:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{cN:"type",b:"\\b[A-Z][\\wÀ-ʸ']*",r:0},a,{cN:"function",bK:"func",e:"{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{b://},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:t,c:["self",a,n,e.CBCM,{b:":"}],i:/["']/}],i:/\[|%/},{cN:"class",bK:"struct protocol class extension enum",k:t,e:"\\{",eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{cN:"meta",b:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain)"},{bK:"import",e:/$/,c:[e.CLCM,s]}]}}),n.registerLanguage("x86asm",function(e){return{cI:!0,l:"[.%]?"+e.IR,k:{keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},c:[e.C(";","$",{r:0}),{cN:"number",v:[{b:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",r:0},{b:"\\$[0-9][0-9A-Fa-f]*",r:0},{b:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{b:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},e.QSM,{cN:"string",v:[{b:"'",e:"[^\\\\]'"},{b:"`",e:"[^\\\\]`"}],r:0},{cN:"symbol",v:[{b:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{b:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],r:0},{cN:"subst",b:"%[0-9]+",r:0},{cN:"subst",b:"%!S+",r:0},{cN:"meta",b:/^\s*\.[\w_-]+/}]}}),n.registerLanguage("yaml",function(e){var t="true false yes no null",s="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",n={cN:"attr",v:[{b:s+r+":"},{b:s+'"'+r+'":'},{b:s+"'"+r+"':"}]},a={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,{cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]}]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[n,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:a.c,e:n.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:t,k:{literal:t}},e.CNM,a]}}),n}); \ No newline at end of file diff --git a/tutorials-book/src/theme/index.hbs b/book/theme/index.hbs similarity index 100% rename from tutorials-book/src/theme/index.hbs rename to book/theme/index.hbs diff --git a/book/tomorrow-night.css b/book/tomorrow-night.css new file mode 100644 index 000000000..f71979258 --- /dev/null +++ b/book/tomorrow-night.css @@ -0,0 +1,104 @@ +/* Tomorrow Night Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.ruby .hljs-constant, +.xml .hljs-tag .hljs-title, +.xml .hljs-pi, +.xml .hljs-doctype, +.html .hljs-doctype, +.css .hljs-id, +.css .hljs-class, +.css .hljs-pseudo { + color: #cc6666; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-preprocessor, +.hljs-pragma, +.hljs-built_in, +.hljs-literal, +.hljs-params, +.hljs-constant { + color: #de935f; +} + +/* Tomorrow Yellow */ +.ruby .hljs-class .hljs-title, +.css .hljs-rule .hljs-attribute { + color: #f0c674; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-value, +.hljs-inheritance, +.hljs-header, +.hljs-name, +.ruby .hljs-symbol, +.xml .hljs-cdata { + color: #b5bd68; +} + +/* Tomorrow Aqua */ +.hljs-title, +.css .hljs-hexcolor { + color: #8abeb7; +} + +/* Tomorrow Blue */ +.hljs-function, +.python .hljs-decorator, +.python .hljs-title, +.ruby .hljs-function .hljs-title, +.ruby .hljs-title .hljs-keyword, +.perl .hljs-sub, +.javascript .hljs-title, +.coffeescript .hljs-title { + color: #81a2be; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.javascript .hljs-function { + color: #b294bb; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1d1f21; + color: #c5c8c6; + padding: 0.5em; + -webkit-text-size-adjust: none; +} + +.coffeescript .javascript, +.javascript .xml, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +} + +.hljs-addition { + color: #718c00; +} + +.hljs-deletion { + color: #c82829; +} diff --git a/book/vectorization.html b/book/vectorization.html new file mode 100644 index 000000000..d26a2d9d0 --- /dev/null +++ b/book/vectorization.html @@ -0,0 +1,268 @@ + + + + + + Introduction to Vectorization - Rust Wrapper for ArrayFire HPC Library + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + +
+
+

Vectorization

+

Programmers and Data Scientists want to take advantage of fast and parallel computational devices. +Writing vectorized code is necessary to get the best performance out of the current generation +parallel hardware and scientific computing software. However, writing vectorized code may not be +immediately intuitive. ArrayFire provides many ways to vectorize a given code segment. In this +chapter, we present several methods to vectorize code using ArrayFire and discuss the benefits and +drawbacks associated with each method.

+

Generic/Default vectorization

+

By its very nature, ArrayFire is a vectorized library. Most functions operate on Arrays as a whole +i.e. on all elements in parallel. For example consider the following code:

+
let mut a = af::range(Dim::new(&[10, 1, 1, 1]));  // [0,  9]
+a = a + 1;                                        // [1, 10]
+
+

This code will result in a single kernel that operates on all 10 elements of a in parallel.

+

A small subset of such vectorized ArrayFire functions are given below for quick reference:

+ + + + + + + + +
Operator CategoryFunctions
Arithmetic operations+, -, *, /, %, >>, <<
Logical operations&&, ||, <, >, ==, != etc.
Numeric functionsabs, floor, round, min, max, etc.
Complex operationsreal, imag, conjg, etc.
Exponential and logarithmic fnsexp, log, expm1, log1p, etc.
Trigonometric functionssin, cos, tan, etc.
Hyperbolic functionssinh, cosh, tanh, etc.
+

In addition to element-wise operations, many other functions are also vectorized in ArrayFire.

+

Notice that even functions that perform some form of aggregation (e.g. sum or min), +signal processing (like convolve), and image processing functions (i.e. rotate etc.)

+
    +
  • all support vectorization on different columns or images.
  • +
+

For example, if we have NUM images of size WIDTHxHEIGHT, one could convolve each image in a +vector fashion as follows:

+
let g_coef: [f32, 9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
+
+let f = Array::new(g_coef, Dim4::new(&[3, 3, 1, 1]));
+let filter = f * 1.0f32/16;
+
+let signal = randu(WIDTH, HEIGHT, NUM);
+let conv   = convolve2(signal, filter, ConvMode::DEFAULT, ConvDomain::AUTO);
+
+

Similarly, one can rotate 100 images by 45 degrees in a single call using code like the following:

+
// Construct an array of 100 WIDTH x HEIGHT images of random numbers
+let imgs = randu(WIDTH, HEIGHT, 100);
+
+// Rotate all of the images in a single command
+let rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR);
+
+

Although most functions in ArrayFire do support vectorization, some do not. Most notably, all +linear algebra functions. Even though they are not vectorized linear algebra operations, they still +execute in parallel on your hardware.

+

Using the built in vectorized operations should be the first and preferred method of vectorizing any +code written with ArrayFire.

+

GFOR

+

This construct is similar to gfor loop from C++ API of ArrayFire. It has not been implemented in +rust wrapper. This section will be updated once the feature has been added to the crate.

+

batch_func

+

This another pending feature that is similar to our C++ API of batchFunc()

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/brush.svg b/brush.svg new file mode 100644 index 000000000..ea266e856 --- /dev/null +++ b/brush.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/build.conf b/build.conf deleted file mode 100644 index 10378045d..000000000 --- a/build.conf +++ /dev/null @@ -1,28 +0,0 @@ -{ - "use_lib": true, - - "build_type" : "Release", - "build_threads" : 3, - "build_cpu" : "ON", - "build_cuda" : "ON", - "build_opencl" : "ON", - "build_nonfree" : "ON", - "build_examples" : "OFF", - "build_test" : "OFF", - - "with_intelmkl" : "OFF", - "with_imageio" : "ON", - "with_graphics" : "ON", - "with_opencl_blas_lib" : "clblast", - - "vcpkg_toolchain_file" : "C:/vcpkg/scripts/buildsystems/vcpkg.cmake", - - "lnx_cuda_sdk": "/opt/cuda", - "lnx_opencl_sdk": "/usr", - "lnx_cuda_host_compiler": "/usr/bin/gcc-6", - - "win_cuda_sdk": "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v9.2", - "win_opencl_sdk": "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v9.2", - "win_cmake_generator": "Visual Studio 15 2017 Win64", - "win_vs_toolset": "v140" -} diff --git a/build.rs b/build.rs deleted file mode 100644 index 43f418495..000000000 --- a/build.rs +++ /dev/null @@ -1,473 +0,0 @@ -/* -- Lots of reuse from: https://github.com/alexcrichton/git2-rs/blob/master/libgit2-sys/build.rs */ -#[macro_use] -extern crate serde_derive; - -extern crate rustc_version; -extern crate serde; -extern crate serde_json; - -use rustc_version::{version, Version}; -use std::convert::AsRef; -use std::env; -use std::fs; -use std::fs::OpenOptions; -use std::io::{ErrorKind, Read}; -use std::path::Path; -use std::path::PathBuf; -use std::process::Command; - -// Windows specific library file names -static WIN_CUDA_LIB: &str = "afcuda"; -static WIN_OCL_LIB: &str = "afopencl"; -static WIN_UNI_LIB: &str = "af"; -// Linux & OSX specific library file names -static UNIX_CUDA_LIB: &str = "libafcuda"; -static UNIX_OCL_LIB: &str = "libafopencl"; -static UNIX_UNI_LIB: &str = "libaf"; - -#[allow(dead_code)] -#[derive(Deserialize, Debug)] -struct Config { - // Use existing arrayfire installation - use_lib: bool, - - // Variables used for building arrayfire submodule - build_type: String, - build_threads: u8, - build_cpu: String, - build_cuda: String, - build_opencl: String, - build_nonfree: String, - build_examples: String, - build_test: String, - - with_intelmkl: String, - with_imageio: String, - with_graphics: String, - with_opencl_blas_lib: String, - - vcpkg_toolchain_file: String, - - lnx_cuda_sdk: String, - lnx_opencl_sdk: String, - lnx_cuda_host_compiler: String, - - win_cuda_sdk: String, - win_opencl_sdk: String, - win_cmake_generator: String, - win_vs_toolset: String, -} - -fn fail(msg: &str) -> ! { - eprintln!("ERROR: {}", msg); - std::process::exit(1); -} - -fn dir_exists(location: &str) -> bool { - match fs::metadata(location) { - Ok(f) => f.is_dir(), - Err(err) => { - if err.kind() != ErrorKind::NotFound { - eprintln!("WARNING: failed to access `{}`: {}", location, err); - } - false - } - } -} - -fn file_exists(location: &str) -> bool { - match fs::metadata(location) { - Ok(f) => f.is_file(), - Err(err) => { - if err.kind() != ErrorKind::NotFound { - eprintln!("WARNING: failed to access `{}`: {}", location, err); - } - false - } - } -} - -fn run(cmd: &mut Command, program: &str) { - println!("running: {:?}", cmd); - let status = match cmd.status() { - Ok(status) => status, - Err(ref e) if e.kind() == ErrorKind::NotFound => { - fail(&format!( - "failed to run cmd: {}\nis `{}` not installed?", - e, program - )); - } - Err(e) => fail(&format!("failed to execute command: {}", e)), - }; - if !status.success() { - fail(&format!( - "command did not execute successfully, got: {}", - status - )); - } -} - -fn read_file(file_name: &std::path::Path) -> String { - let file_path = file_name.to_str().unwrap(); - let options = OpenOptions::new() - .read(true) - .write(false) - .create(false) - .open(&file_path); - - let mut file = match options { - Ok(file) => file, - Err(..) => panic!("error reading file"), - }; - - let mut s = String::new(); - match file.read_to_string(&mut s) { - Ok(_) => s, - Err(..) => panic!("Error reading file to a string"), - } -} - -fn read_conf(conf_file: &std::path::Path) -> Config { - let raw_conf = read_file(conf_file); - let decoded: Config = serde_json::from_str(&raw_conf).unwrap(); - decoded -} - -fn prep_cmake_options(conf: &Config) -> Vec { - let mut options: Vec = vec![]; - - match conf.build_type.as_ref() { - "Release" | "RelWithDebInfo" | "Debug" => { - options.push(format!("-DCMAKE_BUILD_TYPE:STRING={}", conf.build_type)); - } - _ => fail("Invalid value for build_type option"), - }; - match conf.build_cpu.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_BUILD_CPU:BOOL={}", conf.build_cpu)); - } - _ => fail("Invalid value for build_cpu option"), - }; - match conf.build_cuda.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_BUILD_CUDA:BOOL={}", conf.build_cuda)); - } - _ => fail("Invalid value for build_cuda option"), - }; - match conf.build_opencl.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_BUILD_OPENCL:BOOL={}", conf.build_opencl)); - } - _ => fail("Invalid value for build_opencl option"), - }; - match conf.build_nonfree.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_BUILD_NONFREE:BOOL={}", conf.build_nonfree)); - } - _ => fail("Invalid value for build_nonfree option"), - }; - match conf.build_examples.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_BUILD_EXAMPLES:BOOL={}", conf.build_examples)); - } - _ => fail("Invalid value for build_examples option"), - }; - match conf.build_test.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DBUILD_TESTING:BOOL={}", conf.build_test)); - } - _ => fail("Invalid value for build_test option"), - }; - match conf.with_intelmkl.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DUSE_CPU_MKL:BOOL={0}", conf.with_intelmkl)); - options.push(format!("-DUSE_OPENCL_MKL:BOOL={0}", conf.with_intelmkl)); - } - _ => fail("Invalid value for with_intelmkl option"), - }; - match conf.with_imageio.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_WITH_IMAGEIO:BOOL={0}", conf.with_imageio)); - } - _ => fail("Invalid value for with_imageio option"), - }; - match conf.with_graphics.as_ref() { - "ON" | "OFF" => { - options.push(format!("-DAF_WITH_GRAPHICS:BOOL={0}", conf.with_graphics)); - } - _ => fail("Invalid value for with_graphics option"), - }; - match conf.with_opencl_blas_lib.as_ref() { - "clblast" => { - options.push("-DAF_OPENCL_BLAS_LIBRARY:STRING=CLBlast".to_string()); - } - "clblas" => { - options.push("-DAF_OPENCL_BLAS_LIBRARY:STRING=clBLAS".to_string()); - } - _ => fail("Invalid value for with_opencl_blas_lib option"), - }; - options -} - -#[cfg(windows)] -fn run_cmake_command(conf: &Config, build_dir: &std::path::Path) { - let _ = fs::create_dir(&build_dir); - - let options = prep_cmake_options(conf); - - let mut cmake_cmd = Command::new("cmake"); - cmake_cmd.current_dir(&build_dir); - - run( - cmake_cmd - .arg("..") - .arg("-T") - .arg(format!("{}", conf.win_vs_toolset)) - .arg("-G") - .arg(format!("{}", conf.win_cmake_generator)) - .args(&options) - .arg(format!( - "-DCMAKE_TOOLCHAIN_FILE:FILEPATH={}", - conf.vcpkg_toolchain_file - )) - .arg(format!("-DCMAKE_INSTALL_PREFIX={}", "package")), - "cmake", - ); - - let mut make_cmd = Command::new("MSBuild.exe"); - make_cmd.current_dir(&build_dir); - run( - make_cmd - .arg(format!("/m:{}", conf.build_threads)) - .arg(format!("/p:Configuration={}", conf.build_type)) - .arg(format!("ArrayFire.sln")), - "MSBuild", - ); - - let mut install_cmd = Command::new("MSBuild.exe"); - install_cmd.current_dir(&build_dir); - run( - install_cmd - .arg(format!("/p:Configuration={}", conf.build_type)) - .arg(format!("INSTALL.vcxproj")), - "Install", - ); -} - -#[cfg(not(windows))] -fn run_cmake_command(conf: &Config, build_dir: &std::path::Path) { - let _ = fs::create_dir(&build_dir); - - let options = prep_cmake_options(conf); - println!("options are {:?}", options); - - let mut cmake_cmd = Command::new("cmake"); - cmake_cmd.current_dir(&build_dir); - - run( - cmake_cmd - .arg("..") - .args(&options) - .arg(format!("-DCMAKE_INSTALL_PREFIX={}", "package")) - .arg(format!( - "-DCUDA_HOST_COMPILER={}", - conf.lnx_cuda_host_compiler - )), - "cmake", - ); - - let mut make_cmd = Command::new("make"); - make_cmd.current_dir(&build_dir); - run( - make_cmd - .arg(format!("-j{}", conf.build_threads)) - .arg("install"), - "make", - ); -} - -fn backend_exists(name: &str) -> bool { - let win_backend = name.to_string() + ".dll"; - let osx_backend = name.to_string() + ".dylib"; - let linux_backend = name.to_string() + ".so"; - - file_exists(&win_backend) || file_exists(&osx_backend) || file_exists(&linux_backend) -} - -fn blob_backends(conf: &Config, build_dir: &std::path::Path) -> (Vec, Vec) { - let mut backend_dirs: Vec = Vec::new(); - let mut backends: Vec = Vec::new(); - - if conf.use_lib { - let afpath = match env::var("AF_PATH") { - Ok(af_path) => PathBuf::from(&af_path), - Err(_) => { - eprintln!( - "WARNING: USE_LIB is defined, but AF_PATH is not found. Trying to find \ - libraries from known default locations." - ); - if cfg!(target_os = "windows") { - PathBuf::from("C:\\Program Files\\ArrayFire\\v3\\") - } else { - PathBuf::from("/opt/arrayfire/") - } - } - }; - println!("cargo:rerun-if-env-changed=AF_PATH"); - - backend_dirs.push(afpath.join("lib").to_str().to_owned().unwrap().to_string()); - backend_dirs.push( - afpath - .join("lib64") - .to_str() - .to_owned() - .unwrap() - .to_string(), - ); - - if !cfg!(target_os = "windows") { - backend_dirs.push(String::from("/usr/local/lib")); - backend_dirs.push(String::from("/usr/lib")); - } - } else { - backend_dirs.push( - build_dir - .join("package") - .join("lib") - .to_str() - .to_owned() - .unwrap() - .to_string(), - ); - } - - let mut uni_lib_exists = false; - let mut cud_lib_exists = false; - let mut ocl_lib_exists = false; - - for backend_dir in backend_dirs.iter() { - let lib_dir = Path::new(backend_dir); - - let culib_name = if cfg!(windows) { - WIN_CUDA_LIB - } else { - UNIX_CUDA_LIB - }; - cud_lib_exists = - cud_lib_exists || backend_exists(&lib_dir.join(culib_name).to_string_lossy()); - let ocllib_name = if cfg!(windows) { - WIN_OCL_LIB - } else { - UNIX_OCL_LIB - }; - ocl_lib_exists = - ocl_lib_exists || backend_exists(&lib_dir.join(ocllib_name).to_string_lossy()); - let unilib_name = if cfg!(windows) { - WIN_UNI_LIB - } else { - UNIX_UNI_LIB - }; - uni_lib_exists = - uni_lib_exists || backend_exists(&lib_dir.join(unilib_name).to_string_lossy()); - } - - if !conf.use_lib { - // blob in cuda deps - if cud_lib_exists { - if cfg!(windows) { - backend_dirs.push(format!("{}\\lib\\x64", conf.win_cuda_sdk)); - } else { - let sdk_dir = format!("{}/{}", conf.lnx_cuda_sdk, "lib64"); - match dir_exists(&sdk_dir) { - true => { - backend_dirs.push(sdk_dir); - } - false => { - backend_dirs.push(format!("{}/{}", conf.lnx_cuda_sdk, "lib")); - } - }; - } - } - - //blob in opencl deps - if ocl_lib_exists { - if !cfg!(target_os = "macos") { - backends.push("OpenCL".to_string()); - } - if cfg!(windows) { - let sdk_dir = format!("{}\\lib\\x64", conf.win_opencl_sdk); - if dir_exists(&sdk_dir) { - backend_dirs.push(sdk_dir); - } else { - backend_dirs.push(format!("{}\\lib\\x86_64", conf.win_opencl_sdk)); - } - } else { - let sdk_dir = format!("{}/{}", conf.lnx_opencl_sdk, "lib64"); - if dir_exists(&sdk_dir) { - backend_dirs.push(sdk_dir); - } else { - backend_dirs.push(format!("{}/{}", conf.lnx_opencl_sdk, "lib")); - } - } - } - - if conf.with_graphics == "ON" && !conf.use_lib { - backend_dirs.push( - build_dir - .join("third_party") - .join("forge") - .join("lib") - .to_str() - .to_owned() - .unwrap() - .to_string(), - ); - } - } - - if uni_lib_exists { - backends.push("af".to_string()); - if !conf.use_lib && conf.with_graphics == "ON" { - backends.push("forge".to_string()); - } - } - - (backends, backend_dirs) -} - -fn main() { - // Setup pathing - let cargo_manifest_dir = match env::var("CARGO_MANIFEST_DIR") { - Ok(dir_path) => dir_path, - Err(error) => panic!( - "CARGO_MANIFEST_DIR environment variable is not available: {}", - error - ), - }; - let src = Path::new(&cargo_manifest_dir); - let conf_file = src.join("build.conf"); - let conf = read_conf(&conf_file); - - let arrayfire_dir = src.join("arrayfire"); - let build_dir = arrayfire_dir.join("build"); - - if !conf.use_lib { - run_cmake_command(&conf, &build_dir); - } - - let (backends, backend_dirs) = blob_backends(&conf, &build_dir); - - if backends.is_empty() { - fail("no arrayfire backends found"); - } - - for backend in backends.iter() { - println!("cargo:rustc-link-lib=dylib={}", backend); - } - for backend_dir in backend_dirs.iter() { - println!("cargo:rustc-link-search=native={}", backend_dir); - } - if version().unwrap() >= Version::parse("1.8.0").unwrap() { - println!("cargo:rustc-cfg=op_assign"); - } -} diff --git a/cuda-interop/Cargo.toml b/cuda-interop/Cargo.toml deleted file mode 100644 index 0a47799f7..000000000 --- a/cuda-interop/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "af-cuda-interop" -version = "3.7.1" -description = "ArrayFire is a high performance software library for parallel computing with an easy-to-use API. This crate is an addition on top of ArrayFire crate to enable users to mix RAW OpenCL code in rust and ArrayFire." -authors = ["Pradeep Garigipati "] -documentation = "http://arrayfire.github.io/arrayfire-rust/af_cuda_interop/index.html" -homepage = "https://github.com/arrayfire/arrayfire-rust" -repository = "https://github.com/arrayfire/arrayfire-rust/tree/master/cuda-interop" -license = "BSD-3-Clause" -edition = "2018" - -[dependencies] -libc = "0.2" -arrayfire = { path = "../" } -cuda-runtime-sys = "0.3.0-alpha.1" - -[dev-dependencies] -rustacuda = "0.1" -rustacuda_core = "0.1" - -[[example]] -name = "afcuda_custom_kernel" -path = "examples/custom_kernel.rs" - -[[example]] -name = "cuda_af_app" -path = "examples/cuda_af_app.rs" diff --git a/cuda-interop/README.md b/cuda-interop/README.md deleted file mode 100644 index 570bb45c3..000000000 --- a/cuda-interop/README.md +++ /dev/null @@ -1,50 +0,0 @@ -[![ci][19]][16] [![][18]][3] [![][17]][4] - -# ArrayFire CUDA Interop - -This crate is an addition on top of [ArrayFire][1] crate to enable users to mix RAW CUDA code in rust -and [ArrayFire][1]. - -## Supported platforms - -Supported on all platforms [arrayfire-rust][1] is supported. - -## Usage - -Command to build the crate -``` -cargo build -p af_cuda_interop -``` - -Use the following command to run an example -``` -cargo run -p af_cuda_interop --example custom_kernel -``` - -This crate can be used by directly using the packages on crates.io or building them on your own. -The process for this can be found on [arrayfire-rust#readme][2] - -## Acknowledgements - -The ArrayFire library is written by developers at [ArrayFire][14] LLC with [contributions][15] -from several individuals. The developers at ArrayFire LLC have received partial financial support -from several grants and institutions. Those that wish to receive public acknowledgement are listed -below: - -### Grants - -This material is based upon work supported by the DARPA SBIR Program Office under Contract Numbers -W31P4Q-14-C-0012 and W31P4Q-15-C-0008. Any opinions, findings and conclusions or recommendations -expressed in this material are those of the author(s) and do not necessarily reflect the views of -the DARPA SBIR Program Office. - -[1]: https://github.com/arrayfire/arrayfire-rust -[2]: https://github.com/arrayfire/arrayfire-rust/blob/master/README.md -[3]: http://arrayfire.github.io/arrayfire-rust/af_cuda_interop/index.html -[4]: https://join.slack.com/t/arrayfire-org/shared_invite/MjI4MjIzMDMzMTczLTE1MDI5ODg4NzYtN2QwNGE3ODA5OQ -[14]: https://arrayfire.com/ -[15]: https://github.com/arrayfire/arrayfire_rust/graphs/contributors -[16]: https://github.com/arrayfire/arrayfire-rust/actions?workflow=CI -[17]: https://img.shields.io/badge/af_cuda_interop-community-e69138?logo=slack -[18]: https://img.shields.io/badge/af_cuda_interop-Docs-blue?logo=readthedocs -[19]: https://github.com/arrayfire/arrayfire-rust/workflows/ci/badge.svg?event=push diff --git a/cuda-interop/examples/cuda_af_app.rs b/cuda-interop/examples/cuda_af_app.rs deleted file mode 100644 index b1f966cf0..000000000 --- a/cuda-interop/examples/cuda_af_app.rs +++ /dev/null @@ -1,60 +0,0 @@ -use arrayfire::{af_print, dim4, info, set_device, Array}; -use rustacuda::prelude::*; - -fn main() { - // MAKE SURE to do all rustacuda initilization before arrayfire API's - // first call. It seems like some CUDA context state is getting messed up - // if we mix CUDA context init(device, context, module, stream) with ArrayFire API - match rustacuda::init(CudaFlags::empty()) { - Ok(()) => {} - Err(e) => panic!("rustacuda init failure: {:?}", e), - } - let device = match Device::get_device(0) { - Ok(d) => d, - Err(e) => panic!("Failed to get device: {:?}", e), - }; - let _context = - match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { - Ok(c) => c, - Err(e) => panic!("Failed to create context: {:?}", e), - }; - let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { - Ok(s) => s, - Err(e) => panic!("Failed to create stream: {:?}", e), - }; - - let mut in_x = DeviceBuffer::from_slice(&[1.0f32; 10]).unwrap(); - let mut in_y = DeviceBuffer::from_slice(&[2.0f32; 10]).unwrap(); - - // wait for any prior kernels to finish before passing - // the device pointers to ArrayFire - match stream.synchronize() { - Ok(()) => {} - Err(e) => panic!("Stream sync failure: {:?}", e), - }; - - set_device(0); - info(); - - let x = Array::new_from_device_ptr(in_x.as_device_ptr().as_raw_mut(), dim4!(10)); - let y = Array::new_from_device_ptr(in_y.as_device_ptr().as_raw_mut(), dim4!(10)); - - // Lock so that ArrayFire doesn't free pointers from RustaCUDA - // But we have to make sure these pointers stay in valid scope - // as long as the associated ArrayFire Array objects are valid - x.lock(); - y.lock(); - - af_print!("x", x); - af_print!("y", y); - - let o = x + y; - af_print!("out", o); - - let _o_dptr = unsafe { o.device_ptr() }; // Calls an implicit lock - - // User has to call unlock if they want to relenquish control to ArrayFire - - // Once the non-arrayfire operations are done, call unlock. - o.unlock(); // After this, there is no guarantee that value of o_dptr is valid -} diff --git a/cuda-interop/examples/custom_kernel.rs b/cuda-interop/examples/custom_kernel.rs deleted file mode 100644 index c1a012734..000000000 --- a/cuda-interop/examples/custom_kernel.rs +++ /dev/null @@ -1,83 +0,0 @@ -use arrayfire as af; -use rustacuda::prelude::*; -use rustacuda::*; - -use std::ffi::CString; - -fn main() { - // MAKE SURE to do all rustacuda initilization before arrayfire API's - // first call. It seems like some CUDA context state is getting messed up - // if we mix CUDA context init(device, context, module, stream) with ArrayFire API - match rustacuda::init(CudaFlags::empty()) { - Ok(()) => {} - Err(e) => panic!("rustacuda init failure: {:?}", e), - } - let device = match Device::get_device(0) { - Ok(d) => d, - Err(e) => panic!("Failed to get device: {:?}", e), - }; - let _context = - match Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device) { - Ok(c) => c, - Err(e) => panic!("Failed to create context: {:?}", e), - }; - let ptx = CString::new(include_str!("./resources/add.ptx")).unwrap(); - let module = match Module::load_from_string(&ptx) { - Ok(m) => m, - Err(e) => panic!("Failed to load module from string: {:?}", e), - }; - let stream = match Stream::new(StreamFlags::NON_BLOCKING, None) { - Ok(s) => s, - Err(e) => panic!("Failed to create stream: {:?}", e), - }; - - af::set_device(0); - af::info(); - - let num: i32 = 10; - let x = af::constant(1f32, af::dim4!(10)); - let y = af::constant(2f32, af::dim4!(10)); - let out = af::constant(0f32, af::dim4!(10)); - - af::af_print!("x", x); - af::af_print!("y", y); - af::af_print!("out(init)", out); - - //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda - // let af_id = get_device(); - // let cuda_id = get_device_native_id(af_id); - // let af_cuda_stream = get_stream(cuda_id); - - //TODO Figure out how to use Stream returned by ArrayFire with Rustacuda - // let stream = Stream {inner: mem::transmute(af_cuda_stream)}; - - // Run a custom CUDA kernel in the ArrayFire CUDA stream - unsafe { - // Obtain device pointers from ArrayFire using Array::device() method - let d_x: *mut f32 = x.device_ptr() as *mut f32; - let d_y: *mut f32 = y.device_ptr() as *mut f32; - let d_o: *mut f32 = out.device_ptr() as *mut f32; - - match launch!(module.sum<<<1, 1, 0, stream>>>( - memory::DevicePointer::wrap(d_x), - memory::DevicePointer::wrap(d_y), - memory::DevicePointer::wrap(d_o), - num - )) { - Ok(()) => {} - Err(e) => panic!("Kernel Launch failure: {:?}", e), - } - - // wait for the kernel to finish as it is async call - match stream.synchronize() { - Ok(()) => {} - Err(e) => panic!("Stream sync failure: {:?}", e), - }; - - // Return control of Array memory to ArrayFire using unlock - x.unlock(); - y.unlock(); - out.unlock(); - } - af::af_print!("sum after kernel launch", out); -} diff --git a/cuda-interop/examples/resources/add.cu b/cuda-interop/examples/resources/add.cu deleted file mode 100644 index 5db0dbd39..000000000 --- a/cuda-interop/examples/resources/add.cu +++ /dev/null @@ -1,7 +0,0 @@ -extern "C" __constant__ int my_constant = 314; - -extern "C" __global__ void sum(const float* x, const float* y, float* out, int count) { - for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < count; i += blockDim.x * gridDim.x) { - out[i] = x[i] + y[i]; - } -} \ No newline at end of file diff --git a/cuda-interop/examples/resources/add.ptx b/cuda-interop/examples/resources/add.ptx deleted file mode 100644 index cd09eec76..000000000 --- a/cuda-interop/examples/resources/add.ptx +++ /dev/null @@ -1,61 +0,0 @@ -// -// Generated by NVIDIA NVVM Compiler -// -// Compiler Build ID: CL-24817639 -// Cuda compilation tools, release 10.0, V10.0.130 -// Based on LLVM 3.4svn -// - -.version 3.2 -.target sm_20 -.address_size 64 - - // .globl sum -.const .align 4 .u32 my_constant = 314; - -.visible .entry sum( - .param .u64 sum_param_0, - .param .u64 sum_param_1, - .param .u64 sum_param_2, - .param .u32 sum_param_3 -) -{ - .reg .pred %p<3>; - .reg .f32 %f<4>; - .reg .b32 %r<11>; - .reg .b64 %rd<11>; - - - ld.param.u64 %rd4, [sum_param_0]; - ld.param.u64 %rd5, [sum_param_1]; - ld.param.u64 %rd6, [sum_param_2]; - ld.param.u32 %r6, [sum_param_3]; - mov.u32 %r1, %ntid.x; - mov.u32 %r7, %ctaid.x; - mov.u32 %r8, %tid.x; - mad.lo.s32 %r10, %r1, %r7, %r8; - setp.ge.s32 %p1, %r10, %r6; - @%p1 bra BB0_3; - - cvta.to.global.u64 %rd1, %rd6; - cvta.to.global.u64 %rd2, %rd5; - cvta.to.global.u64 %rd3, %rd4; - mov.u32 %r9, %nctaid.x; - mul.lo.s32 %r3, %r9, %r1; - -BB0_2: - mul.wide.s32 %rd7, %r10, 4; - add.s64 %rd8, %rd3, %rd7; - add.s64 %rd9, %rd2, %rd7; - ld.global.f32 %f1, [%rd9]; - ld.global.f32 %f2, [%rd8]; - add.f32 %f3, %f2, %f1; - add.s64 %rd10, %rd1, %rd7; - st.global.f32 [%rd10], %f3; - add.s32 %r10, %r3, %r10; - setp.lt.s32 %p2, %r10, %r6; - @%p2 bra BB0_2; - -BB0_3: - ret; -} \ No newline at end of file diff --git a/cuda-interop/src/lib.rs b/cuda-interop/src/lib.rs deleted file mode 100644 index da66e48b5..000000000 --- a/cuda-interop/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! af-cuda-interop package is to used only when the application intends to mix -//! arrayfire code with raw CUDA code. - -use arrayfire::{handle_error_general, AfError}; -use cuda_runtime_sys::cudaStream_t; -use libc::c_int; - -extern "C" { - fn afcu_get_native_id(native_id: *mut c_int, id: c_int) -> c_int; - fn afcu_set_native_id(native_id: c_int) -> c_int; - fn afcu_get_stream(out: *mut cudaStream_t, id: c_int) -> c_int; -} - -/// Get active device's id in CUDA context -/// -/// # Parameters -/// -/// - `id` is the integer identifier of concerned CUDA device as per ArrayFire context -/// -/// # Return Values -/// -/// Integer identifier of device in CUDA context -pub fn get_device_native_id(id: i32) -> i32 { - unsafe { - let mut temp: i32 = 0; - let err_val = afcu_get_native_id(&mut temp as *mut c_int, id); - handle_error_general(AfError::from(err_val)); - temp - } -} - -/// Set active device using CUDA context's id -/// -/// # Parameters -/// -/// - `id` is the identifier of GPU in CUDA context -pub fn set_device_native_id(native_id: i32) { - unsafe { - let err_val = afcu_set_native_id(native_id); - handle_error_general(AfError::from(err_val)); - } -} - -/// Get CUDA stream of active CUDA device -/// -/// # Parameters -/// -/// - `id` is the identifier of device in ArrayFire context -/// -/// # Return Values -/// -/// [cudaStream_t](https://docs.rs/cuda-runtime-sys/0.3.0-alpha.1/cuda_runtime_sys/type.cudaStream_t.html) handle. -pub fn get_stream(native_id: i32) -> cudaStream_t { - unsafe { - let mut ret_val: cudaStream_t = std::ptr::null_mut(); - let err_val = afcu_get_stream(&mut ret_val as *mut cudaStream_t, native_id); - handle_error_general(AfError::from(err_val)); - ret_val - } -} diff --git a/dark.css b/dark.css new file mode 100644 index 000000000..b49cae1c1 --- /dev/null +++ b/dark.css @@ -0,0 +1 @@ +body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.logo-container.rust-logo>img{filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff)}*{scrollbar-color:rgb(64,65,67) #717171;}.sidebar{scrollbar-color:rgba(32,34,37,.6) transparent;}::-webkit-scrollbar-track{background-color:#717171;}::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar::-webkit-scrollbar-track{background-color:#717171;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(32,34,37,.6);}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav:not(.sidebar){border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a,#help a{color:#D2991D;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}.search-focus:disabled{background-color:#c5c4c4;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{color:#ddd;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);color:black;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;border-right:3px solid #bb7410;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.8);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.8);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.8);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.8);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:#000;color:#fff;border-color:#000;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#111;border-color:#777;}#titles>div:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background:#f0f0f0;color:#000;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;} \ No newline at end of file diff --git a/down-arrow.svg b/down-arrow.svg new file mode 100644 index 000000000..35437e77a --- /dev/null +++ b/down-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/acoustic_wave.rs b/examples/acoustic_wave.rs deleted file mode 100644 index a7f064f92..000000000 --- a/examples/acoustic_wave.rs +++ /dev/null @@ -1,87 +0,0 @@ -use arrayfire::*; -use std::f64::consts::*; - -fn main() { - set_device(0); - info(); - acoustic_wave_simulation(); -} - -fn normalise(a: &Array) -> Array { - (a / (max_all(&abs(a)).0 as f32 * 2.0f32)) + 0.5f32 -} - -fn acoustic_wave_simulation() { - // Speed of sound - let c: f32 = 0.1; - // Distance step - let dx: f32 = 0.5; - // Time step - let dt: f32 = 1.0; - - // Grid size. - let nx: u64 = 1500; - let ny: u64 = 1500; - - // Grid dimensions. - let dims = Dim4::new(&[nx, ny, 1, 1]); - - // Pressure field - let mut p = constant::(0.0, dims); - // d(pressure)/dt field - let mut p_dot = p.clone(); - - // Laplacian (Del^2) convolution kernel. - let laplacian_values: [f32; 9] = [0.0, 1.0, 0.0, 1.0, -4.0, 1.0, 0.0, 1.0, 0.0]; - let laplacian_kernel = Array::new(&laplacian_values, Dim4::new(&[3, 3, 1, 1])) / (dx * dx); - - // Create a window to show the waves. - let mut win = Window::new(1000, 1000, "Waves".to_string()); - - // Hann windowed pulse. - let pulse_time: f32 = 100.0; - let centre_freq: f32 = 0.05; - let twopi = PI as f32 * 2.0; - - // Number of samples in pulse. - let pulse_n = (pulse_time / dt).floor() as u64; - - let i = range::(Dim4::new(&[pulse_n, 1, 1, 1]), 0); - let t = i.clone() * dt; - let hmg_wnd = cos(&(i * (twopi / pulse_n as f32))) * -0.46f32 + 0.54f32; - let wave = sin(&(&t * centre_freq * twopi)); - let pulse = wave * hmg_wnd; - - // Iteration count. - let mut it = 0; - - while !win.is_closed() { - // Convole with laplacian to get spacial second derivative. - let lap_p = convolve2( - &p, - &laplacian_kernel, - ConvMode::DEFAULT, - ConvDomain::SPATIAL, - ); - // Calculate the updated pressure and d(pressure)/dt fields. - p_dot += lap_p * (c * dt); - p += &p_dot * dt; - - if it < pulse_n { - // Location of the source. - let seqs = &[Seq::new(700.0, 800.0, 1.0), Seq::new(800.0, 800.0, 1.0)]; - // Set the pressure there. - assign_seq( - &mut p, - seqs, - &index(&pulse, &[Seq::new(it as f64, it as f64, 1.0)]), - ); - } - - // Draw the image. - win.set_colormap(ColorMap::BLUE); - win.draw_image(&normalise(&p), None); - - it += 1; - } -} diff --git a/examples/conway.rs b/examples/conway.rs deleted file mode 100644 index 8762a8a05..000000000 --- a/examples/conway.rs +++ /dev/null @@ -1,29 +0,0 @@ -use arrayfire::*; - -fn main() { - set_device(0); - info(); - conways_game_of_life(); -} - -fn normalise(a: &Array) -> Array { - a / (max_all(&abs(a)).0 as f32) -} - -fn conways_game_of_life() { - let h_kernel = [1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0]; - let kernel = Array::new(&h_kernel, Dim4::new(&[3, 3, 1, 1])); - let s = constant::(0.5, Dim4::new(&[1, 1, 1, 1])); - let mut state = gt(&randu::(Dim4::new(&[256, 256, 3, 1])), &s, false); - let c0 = constant::(2.0, Dim4::new(&[1, 1, 1, 1])); - let c1 = constant::(3.0, Dim4::new(&[1, 1, 1, 1])); - - let win = Window::new(512, 512, "Game of Life".to_string()); - while !win.is_closed() { - let n_hood = convolve2(&state, &kernel, ConvMode::DEFAULT, ConvDomain::SPATIAL); - let c0 = &eq(&n_hood, &c0, false); - let c1 = &eq(&n_hood, &c1, false); - state = state * c0 + c1; - win.draw_image(&normalise(&state.cast::()), None); - } -} diff --git a/examples/fft.rs b/examples/fft.rs deleted file mode 100644 index 368ed49b0..000000000 --- a/examples/fft.rs +++ /dev/null @@ -1,31 +0,0 @@ -use arrayfire::*; -use num::Complex; - -fn main() { - set_device(0); - info(); - let samples = 10; - let dims = Dim4::new(&[samples, 1, 1, 1]); - - let values = vec![ - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - Complex::new(0.0, 2.0), - ]; - - let signal = Array::new(&values, dims); - - af_print!("signal", signal); - - // Used length of input signal as norm_factor - let output = fft(&signal, 0.1, samples as i64); - - af_print!("Output", output); -} diff --git a/examples/helloworld.rs b/examples/helloworld.rs deleted file mode 100644 index 5e455425d..000000000 --- a/examples/helloworld.rs +++ /dev/null @@ -1,90 +0,0 @@ -use arrayfire::*; - -#[allow(unused_must_use)] -fn main() { - set_device(0); - info(); - print!("Info String:\n{}", info_string(true)); - println!("Arrayfire version: {:?}", get_version()); - let (name, platform, toolkit, compute) = device_info(); - print!( - "Name: {}\nPlatform: {}\nToolkit: {}\nCompute: {}\n", - name, platform, toolkit, compute - ); - println!("Revision: {}", get_revision()); - - let num_rows: i64 = 5; - let num_cols: i64 = 3; - let values: [f32; 3] = [1.0, 2.0, 3.0]; - let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); - - af_print!("Indices ", indices); - - let dims = Dim4::new(&[num_rows as u64, num_cols as u64, 1, 1]); - - let mut a = randu::(dims); - af_print!("Create a 5-by-3 float matrix on the GPU", a); - - println!("Element-wise arithmetic"); - let b = add(&sin(&a), &1.5f32, false); - - let b2 = add(&sin(&a), &cos(&a), false); - - let b3 = !&a; - af_print!("sin(a) + 1.5 a.k.a b => ", b); - af_print!("sin(a) + cos(a) => ", b2); - af_print!("!a => ", b3); - - let test = a.clone() + b.clone(); - af_print!("a + b", test); - - let negation = -(a.clone()); - af_print!("-a ", negation); - - // Index array using sequences - let seqs = &[Seq::new(1u32, 3, 1), Seq::default()]; - let sub = index(&a, seqs); - af_print!("a(seq(1,3,1), span)", sub); - - //Index array using array and sequence - let seq4gen = Seq::new(0u32, 2, 1); - - let mut idxrs = Indexer::default(); - idxrs.set_index(&indices, 0, None); - idxrs.set_index(&seq4gen, 1, Some(false)); - - let sub2 = index_gen(&a, idxrs); - af_print!("a(indices, seq(0, 2, 1))", sub2); - - println!("Fourier transform the result"); - print(&fft(&b, 1.0, 0)); - - println!("Grab last row & col of the random matrix"); - print(&a); - print(&row(&a, num_rows - 1)); - print(&col(&a, num_cols - 1)); - - let r_dims = Dim4::new(&[3, 1, 1, 1]); - let r_input: [f32; 3] = [1.0, 1.0, 1.0]; - let r = Array::new(&r_input, r_dims); - set_row(&mut a, &r, num_rows - 1); - af_print!("Set last row to 1's", a); - - let d_dims = Dim4::new(&[2, 3, 1, 1]); - let d_input: [i32; 6] = [1, 2, 3, 4, 5, 6]; - let d = Array::new(&d_input, d_dims); - af_print!("Create 2-by-3 matrix from host data", d); - - //// // Sort A - //println!("Sort A and print sorted array and corresponding indices"); - //let x = sort_index(&a, 0, true); - //print(&x.0); - //print(&x.1); - - let u8_cnst = &constant(1_u8, dims); - af_print!("u8 constant array", u8_cnst); - println!( - "Is u8_cnst array float precision type ? {}", - u8_cnst.is_single() - ); -} diff --git a/examples/histogram.rs b/examples/histogram.rs deleted file mode 100644 index 4e596bd18..000000000 --- a/examples/histogram.rs +++ /dev/null @@ -1,39 +0,0 @@ -use arrayfire::*; -use std::env; -use std::path::PathBuf; - -#[allow(unused_variables)] -#[allow(unused_must_use)] -fn main() { - set_device(0); - info(); - - let assets_dir = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()) - .join("arrayfire") - .join("assets") - .join("examples") - .join("images"); - - let img_wnd = Window::new(480, 640, String::from("Input Image")); - img_wnd.set_position(100, 100); - - let hst_wnd = Window::new(512, 512, String::from("Input Image Histogram")); - hst_wnd.set_position(600, 100); - - let man = load_image::(format!("{}/man.jpg", assets_dir.display()), false); - let hst = histogram(&man, 256, 0.0, 255.0); - - let disp_img = div(&man, &constant(255_f32, man.dims()), false); - - loop { - img_wnd.draw_image(&disp_img, None); - hst_wnd.draw_hist(&hst, 0.0, 255.0, None); - - if img_wnd.is_closed() { - break; - } - if hst_wnd.is_closed() { - break; - } - } -} diff --git a/examples/neural_network.rs b/examples/neural_network.rs deleted file mode 100644 index 4fcb92a86..000000000 --- a/examples/neural_network.rs +++ /dev/null @@ -1,389 +0,0 @@ -use self::{ - ann::ArtificialNeuralNetworkBuilder, arrayfire_mnist::ArrayfireNormalizedMnist, model::Model, -}; - -use arrayfire::Array; - -use mnist::MnistBuilder; - -pub(crate) mod arrayfire_mnist { - use arrayfire::{dim4, transpose, Array}; - use mnist::NormalizedMnist; - - pub const TRAINING_SET_SIZE: u32 = 6_000; - pub const VALIDATION_SET_SIZE: u32 = 1_000; - pub const TEST_SET_SIZE: u32 = 1_000; - pub const IMAGE_DIMENSION: usize = 28; - pub struct ArrayfireNormalizedMnist { - pub training_labels: Array, - pub training_images: Array, - pub validation_labels: Array, - pub validation_images: Array, - pub testing_labels: Array, - pub testing_images: Array, - } - - impl From<&NormalizedMnist> for ArrayfireNormalizedMnist { - fn from(mnist_data: &NormalizedMnist) -> Self { - let training_images = Array::new( - &mnist_data.trn_img, - dim4![ - (IMAGE_DIMENSION * IMAGE_DIMENSION) as u64, - TRAINING_SET_SIZE as u64, - 1, - 1 - ], - ); - let training_labels = Array::new( - &mnist_data.trn_lbl, - dim4![10, TRAINING_SET_SIZE as u64, 1, 1], - ); - - let testing_images = Array::new( - &mnist_data.tst_img, - dim4![ - (IMAGE_DIMENSION * IMAGE_DIMENSION) as u64, - TEST_SET_SIZE as u64, - 1, - 1 - ], - ); - let testing_labels = - Array::new(&mnist_data.tst_lbl, dim4![10, TEST_SET_SIZE as u64, 1, 1]); - - let validation_images = Array::new( - &mnist_data.val_img, - dim4![ - (IMAGE_DIMENSION * IMAGE_DIMENSION) as u64, - VALIDATION_SET_SIZE as u64, - 1, - 1 - ], - ); - let validation_labels = Array::new( - &mnist_data.val_lbl, - dim4![10, VALIDATION_SET_SIZE as u64, 1, 1], - ); - - ArrayfireNormalizedMnist { - training_labels: transpose(&training_labels, false), - training_images: transpose(&training_images, false), - validation_labels: transpose(&validation_labels, false), - validation_images: transpose(&validation_images, false), - testing_labels: transpose(&testing_labels, false), - testing_images: transpose(&testing_images, false), - } - } - } -} -pub(crate) mod model { - use arrayfire::Array; - pub trait Model { - fn predict(&self, feature: &Array) -> Array; - - fn train( - &mut self, - training_features: &Array, - training_labels: &Array, - validation_features: &Array, - validation_labels: &Array, - learning_rate_alpha: f64, - max_epochs: i32, - batch_size: i32, - max_err: f64, - ) -> f64; - } -} -mod ann { - use super::model::Model; - use arrayfire::{ - constant, dim4, index, join, matmul, seq, sigmoid, sum_all, transpose, Array, MatProp, - }; - pub struct ArtificialNeuralNetwork { - weights: Vec>, - num_layers: usize, - } - - pub struct ArtificialNeuralNetworkBuilder { - feature_width: usize, - layer_widths: Vec, - label_width: usize, - initial_random_range: f32, - num_layers: usize, - } - - impl ArtificialNeuralNetworkBuilder { - pub fn new() -> ArtificialNeuralNetworkBuilder { - ArtificialNeuralNetworkBuilder { - feature_width: 0, - label_width: 0, - num_layers: 2, - layer_widths: vec![], - initial_random_range: 0.05, - } - } - - pub fn with_feature_width( - &mut self, - feature_width: usize, - ) -> &mut ArtificialNeuralNetworkBuilder { - self.feature_width = feature_width; - self - } - - pub fn with_label_width( - &mut self, - label_width: usize, - ) -> &mut ArtificialNeuralNetworkBuilder { - self.label_width = label_width; - self - } - - pub fn add_hidden_layer( - &mut self, - layer_width: usize, - ) -> &mut ArtificialNeuralNetworkBuilder { - self.layer_widths.push(layer_width); - self.num_layers += 1; - self - } - - pub fn with_initial_random_range( - &mut self, - range: f32, - ) -> &mut ArtificialNeuralNetworkBuilder { - self.initial_random_range = range; - self - } - - pub fn build(&self) -> ArtificialNeuralNetwork { - let mut widths: Vec = vec![]; - widths.push(self.feature_width); - widths.append(&mut self.layer_widths.clone()); - widths.push(self.label_width); - - let mut weights = vec![]; - for index in 0..(widths.len() - 1) { - weights.push( - self.initial_random_range - * arrayfire::randu::(dim4![ - widths[index] as u64 + 1, - widths[index + 1] as u64, - 1, - 1 - ]) - - self.initial_random_range / 2f32, - ) - } - ArtificialNeuralNetwork { - weights, - num_layers: self.num_layers, - } - } - } - - impl Model for ArtificialNeuralNetwork { - fn train( - &mut self, - training_features: &Array, - training_labels: &Array, - validation_features: &Array, - validation_labels: &Array, - learning_rate_alpha: f64, - max_epochs: i32, - batch_size: i32, - max_err: f64, - ) -> f64 { - let number_of_training_samples = training_features.dims()[0] as i32; - let number_of_batches_in_training_set = number_of_training_samples / batch_size; - - let validation_batch_size = 1; - - let _number_of_validation_samples = validation_features.dims()[0] as i32; - let number_of_batches_in_validation_set = 1; //number_of_validation_samples / validation_batch_size; - - let mut avg_error = 0f64; - - for epoch in 0..max_epochs { - let mut errors = Vec::with_capacity(number_of_batches_in_validation_set as usize); - for training_batch in 0..number_of_batches_in_training_set { - let start = training_batch * batch_size; - let end = start + batch_size - 1; - - let features = index(training_features, &[seq![start, end, 1], seq!()]); - let labels = index(training_labels, &[seq![start, end, 1], seq!()]); - - let signals = self.forward_propagate(&features); - - self.back_propagate(&signals, &labels, learning_rate_alpha); - } - - for validation_batch in 0..number_of_batches_in_validation_set { - let start = validation_batch * validation_batch_size; - let end = start + validation_batch_size - 1; - - let prediction = - self.predict(&index(validation_features, &[seq![start, end, 1], seq!()])); - - let target = &index(validation_labels, &[seq![start, end, 1], seq!()]); - - errors.push(Self::error(&prediction, target)); - } - - avg_error = errors.clone().into_iter().sum::() - / (number_of_batches_in_validation_set) as f64; - if avg_error < max_err { - println!("Converged on Epoch: {}", epoch + 1); - return avg_error; - } - - if (epoch + 1) % 10 == 0 { - println!("Epoch: {}, Error: {}", epoch + 1, avg_error); - } - } - avg_error - } - - fn predict(&self, input: &Array) -> Array { - let signal = self.forward_propagate(input); - signal.last().unwrap().copy() - } - } - - impl ArtificialNeuralNetwork { - fn forward_propagate(&self, input: &Array) -> Vec> { - //first layer is the input - let mut signal = Vec::with_capacity(self.num_layers); - - signal.push(input.copy()); - - for layer_index in 0..(self.num_layers - 1) { - let signal_with_bias: Array = Self::add_bias(&signal[layer_index]); - let output = matmul( - &signal_with_bias, - &self.weights[layer_index], - MatProp::NONE, - MatProp::NONE, - ); - signal.push(sigmoid(&output)); - } - - signal - } - - fn add_bias(array: &Array) -> Array { - join( - 1, - &constant::(1f32, dim4![array.dims()[0], 1, 1, 1]), - array, - ) - } - - fn deriv(out: &Array) -> Array { - out * (1 - out) - } - - fn back_propagate( - &mut self, - signals: &Vec>, - labels: &Array, - learning_rate_alpha: f64, - ) { - let mut output = signals.last().unwrap(); - let mut error = output - labels; - - let m = labels.dims()[0] as i32; - - for layer_index in (0..self.num_layers - 1).rev() { - let signal = Self::add_bias(&signals[layer_index]); - let delta = transpose(&(Self::deriv(output) * error), false); - - let tg = - learning_rate_alpha * matmul(&delta, &signal, MatProp::NONE, MatProp::NONE); - let gradient = -(tg) / m; - self.weights[layer_index] += transpose(&gradient, false); - - output = &signals[layer_index]; - - let err = &matmul( - &transpose(&delta, false), - &transpose(&self.weights[layer_index], false), - MatProp::NONE, - MatProp::NONE, - ); - - error = index(err, &[seq!(), seq!(1, output.dims()[1] as i32, 1)]); - } - } - - fn error(prediction: &Array, target: &Array) -> f64 { - let dif = (prediction - target) * 1f64; - let sum = sum_all(&(&dif * &dif)).0; - sum.sqrt() - } - } -} - -fn accuracy(predicted: &Array, target: &Array) -> f32 { - let (_target_maximums, target_max_indices) = arrayfire::imax(target, 1); - let (_predicted_maximums, predicted_max_indices) = arrayfire::imax(predicted, 1); - - let (matches, _) = arrayfire::count_all(&arrayfire::eq( - &target_max_indices, - &predicted_max_indices, - false, - )); - 100f32 * matches as f32 / target_max_indices.elements() as f32 -} - -fn main() { - arrayfire::info(); - println!("** ArrayFire-Rust ANN Demo **\n"); - - let mnist = MnistBuilder::new() - .label_format_one_hot() - .training_set_length(50_000) - .validation_set_length(10_000) - .test_set_length(10_000) - .download_and_extract() - .finalize() - .normalize(); - - let mnist = ArrayfireNormalizedMnist::from(&mnist); - - let mut model = ArtificialNeuralNetworkBuilder::new() - .with_feature_width(28 * 28) - .with_label_width(10) - .add_hidden_layer(100) - .add_hidden_layer(50) - .with_initial_random_range(0.05f32) - .build(); - - model.train( - &mnist.training_images, - &mnist.training_labels, - &mnist.validation_images, - &mnist.validation_labels, - 2.0, - 250, - 100, - 0.05, - ); - - let train_output = model.predict(&mnist.training_images); - let test_output = model.predict(&mnist.testing_images); - - arrayfire::sync(arrayfire::get_device()); - - println!("\nTraining set:"); - println!( - "Accuracy on training data: {}", - accuracy(&train_output, &(mnist.training_labels * 1f32)), - ); - - println!("\nTest set:"); - println!( - "Accuracy on testing data: {}", - accuracy(&test_output, &(mnist.testing_labels * 1f32)), - ); -} diff --git a/examples/pi.rs b/examples/pi.rs deleted file mode 100644 index f180478b7..000000000 --- a/examples/pi.rs +++ /dev/null @@ -1,32 +0,0 @@ -use arrayfire::*; -use std::time::Instant; - -#[allow(unused_must_use)] -#[allow(unused_variables)] -fn main() { - set_device(0); - info(); - let samples = 20_000_000; - let dims = Dim4::new(&[samples, 1, 1, 1]); - - let x = &randu::(dims); - let y = &randu::(dims); - - let start = Instant::now(); - - mem_info!("Before benchmark"); - - for bench_iter in 0..100 { - let xsqrd = &mul(x, x, false); - let ysqrd = &mul(y, y, false); - let xplusy = &add(xsqrd, ysqrd, false); - let root = &sqrt(xplusy); - let cnst = &constant(1, dims); - let (real, imag) = sum_all(&le(root, cnst, false)); - let pi_val = (real as f64) * 4.0 / (samples as f64); - } - - println!("Estimated Pi Value in {:?}", start.elapsed()); - - mem_info!("After benchmark"); -} diff --git a/examples/snow.rs b/examples/snow.rs deleted file mode 100644 index 0c317cac1..000000000 --- a/examples/snow.rs +++ /dev/null @@ -1,20 +0,0 @@ -use arrayfire::*; - -#[allow(unused_variables)] -#[allow(unused_must_use)] -fn main() { - set_device(0); - info(); - - let wnd = Window::new(1280, 720, String::from("Snow")); - - let dims = Dim4::new(&[1280, 720, 3, 1]); - - loop { - wnd.draw_image(&randu::(dims), None); - - if wnd.is_closed() { - break; - } - } -} diff --git a/examples/unified.rs b/examples/unified.rs deleted file mode 100644 index e70aa5d6d..000000000 --- a/examples/unified.rs +++ /dev/null @@ -1,56 +0,0 @@ -use arrayfire::*; - -#[cfg(op_assign)] -fn helper(dims: Dim4) { - let mut a = randu::(dims); - let b = randu::(dims); - print(&a); - print(&b); - a += b; - print(&a); -} - -#[cfg(not(op_assign))] -fn helper(dims: Dim4) { - let b = randu::(dims); - print(&b); -} - -#[allow(unused_must_use)] -fn test_backend() { - info(); - - println!("Create a 10-by-10 matrix of random floats on the compute device"); - let num_rows: u64 = 10; - let num_cols: u64 = 10; - let dims = Dim4::new(&[num_rows, num_cols, 1, 1]); - - helper(dims) -} - -#[allow(unused_must_use)] -fn main() { - println!("There are {:?} available backends", get_backend_count()); - let available = get_available_backends(); - - if available.contains(&Backend::CPU) { - println!("Evaluating CPU Backend..."); - set_backend(Backend::CPU); - println!("There are {} CPU compute devices", device_count()); - test_backend(); - } - - if available.contains(&Backend::CUDA) { - println!("Evaluating CUDA Backend..."); - set_backend(Backend::CUDA); - println!("There are {} CUDA compute devices", device_count()); - test_backend(); - } - - if available.contains(&Backend::OPENCL) { - println!("Evaluating OpenCL Backend..."); - set_backend(Backend::OPENCL); - println!("There are {} OpenCL compute devices", device_count()); - test_backend(); - } -} diff --git a/examples/using_half.rs b/examples/using_half.rs deleted file mode 100644 index 1c447f817..000000000 --- a/examples/using_half.rs +++ /dev/null @@ -1,15 +0,0 @@ -use arrayfire::*; -use half::f16; - -fn main() { - set_device(0); - info(); - - let values: Vec<_> = (1u8..101).map(std::convert::From::from).collect(); - - let half_values = values.iter().map(|&x| f16::from_f32(x)).collect::>(); - - let hvals = Array::new(&half_values, Dim4::new(&[10, 10, 1, 1])); - - print(&hvals); -} diff --git a/favicon-16x16.png b/favicon-16x16.png new file mode 100644 index 000000000..7cfe6c135 Binary files /dev/null and b/favicon-16x16.png differ diff --git a/favicon-32x32.png b/favicon-32x32.png new file mode 100644 index 000000000..5109c1de8 Binary files /dev/null and b/favicon-32x32.png differ diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 000000000..8b34b5119 --- /dev/null +++ b/favicon.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/implementors/arrayfire/trait.ComplexFloating.js b/implementors/arrayfire/trait.ComplexFloating.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ComplexFloating.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ConfidenceCCInput.js b/implementors/arrayfire/trait.ConfidenceCCInput.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ConfidenceCCInput.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ConstGenerator.js b/implementors/arrayfire/trait.ConstGenerator.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ConstGenerator.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.Convertable.js b/implementors/arrayfire/trait.Convertable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.Convertable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.CovarianceComputable.js b/implementors/arrayfire/trait.CovarianceComputable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.CovarianceComputable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.DeconvInput.js b/implementors/arrayfire/trait.DeconvInput.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.DeconvInput.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.EdgeComputable.js b/implementors/arrayfire/trait.EdgeComputable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.EdgeComputable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.FloatingPoint.js b/implementors/arrayfire/trait.FloatingPoint.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.FloatingPoint.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.Fromf64.js b/implementors/arrayfire/trait.Fromf64.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.Fromf64.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.GrayRGBConvertible.js b/implementors/arrayfire/trait.GrayRGBConvertible.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.GrayRGBConvertible.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.HasAfEnum.js b/implementors/arrayfire/trait.HasAfEnum.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.HasAfEnum.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ImageFilterType.js b/implementors/arrayfire/trait.ImageFilterType.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ImageFilterType.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ImageNativeType.js b/implementors/arrayfire/trait.ImageNativeType.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ImageNativeType.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ImplicitPromote.js b/implementors/arrayfire/trait.ImplicitPromote.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ImplicitPromote.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.Indexable.js b/implementors/arrayfire/trait.Indexable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.Indexable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.IndexableType.js b/implementors/arrayfire/trait.IndexableType.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.IndexableType.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.IntegralType.js b/implementors/arrayfire/trait.IntegralType.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.IntegralType.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.MedianComputable.js b/implementors/arrayfire/trait.MedianComputable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.MedianComputable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.MomentsComputable.js b/implementors/arrayfire/trait.MomentsComputable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.MomentsComputable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.RealFloating.js b/implementors/arrayfire/trait.RealFloating.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.RealFloating.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.RealNumber.js b/implementors/arrayfire/trait.RealNumber.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.RealNumber.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.ReduceByKeyInput.js b/implementors/arrayfire/trait.ReduceByKeyInput.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.ReduceByKeyInput.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/arrayfire/trait.Scanable.js b/implementors/arrayfire/trait.Scanable.js new file mode 100644 index 000000000..3c69bcfad --- /dev/null +++ b/implementors/arrayfire/trait.Scanable.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 000000000..cea29ba06 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Clone for VendorPlatform","synthetic":false,"types":[]},{"text":"impl Clone for DeviceType","synthetic":false,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl<T> Clone for Array<T> where
    T: HasAfEnum, 
","synthetic":false,"types":[]},{"text":"impl Clone for AfError","synthetic":false,"types":[]},{"text":"impl Clone for Backend","synthetic":false,"types":[]},{"text":"impl Clone for DType","synthetic":false,"types":[]},{"text":"impl Clone for InterpType","synthetic":false,"types":[]},{"text":"impl Clone for BorderType","synthetic":false,"types":[]},{"text":"impl Clone for Connectivity","synthetic":false,"types":[]},{"text":"impl Clone for ConvMode","synthetic":false,"types":[]},{"text":"impl Clone for ConvDomain","synthetic":false,"types":[]},{"text":"impl Clone for MatchType","synthetic":false,"types":[]},{"text":"impl Clone for ColorSpace","synthetic":false,"types":[]},{"text":"impl Clone for MatProp","synthetic":false,"types":[]},{"text":"impl Clone for NormType","synthetic":false,"types":[]},{"text":"impl Clone for ColorMap","synthetic":false,"types":[]},{"text":"impl Clone for YCCStd","synthetic":false,"types":[]},{"text":"impl Clone for HomographyType","synthetic":false,"types":[]},{"text":"impl Clone for MarkerType","synthetic":false,"types":[]},{"text":"impl Clone for MomentType","synthetic":false,"types":[]},{"text":"impl Clone for SparseFormat","synthetic":false,"types":[]},{"text":"impl Clone for BinaryOp","synthetic":false,"types":[]},{"text":"impl Clone for RandomEngineType","synthetic":false,"types":[]},{"text":"impl Clone for Scalar","synthetic":false,"types":[]},{"text":"impl Clone for CannyThresholdType","synthetic":false,"types":[]},{"text":"impl Clone for DiffusionEq","synthetic":false,"types":[]},{"text":"impl Clone for FluxFn","synthetic":false,"types":[]},{"text":"impl Clone for TopkFn","synthetic":false,"types":[]},{"text":"impl Clone for IterativeDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Clone for InverseDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Clone for ConvGradientType","synthetic":false,"types":[]},{"text":"impl Clone for VarianceBias","synthetic":false,"types":[]},{"text":"impl Clone for CublasMathMode","synthetic":false,"types":[]},{"text":"impl Clone for Dim4","synthetic":false,"types":[]},{"text":"impl Clone for RandomEngine","synthetic":false,"types":[]},{"text":"impl<T: Clone + IndexableType> Clone for Seq<T>","synthetic":false,"types":[]},{"text":"impl Clone for Window","synthetic":false,"types":[]},{"text":"impl Clone for Features","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialEq.js b/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 000000000..34d9b1f9d --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl PartialEq<VendorPlatform> for VendorPlatform","synthetic":false,"types":[]},{"text":"impl PartialEq<DeviceType> for DeviceType","synthetic":false,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl PartialEq<AfError> for AfError","synthetic":false,"types":[]},{"text":"impl PartialEq<Backend> for Backend","synthetic":false,"types":[]},{"text":"impl PartialEq<DType> for DType","synthetic":false,"types":[]},{"text":"impl PartialEq<InterpType> for InterpType","synthetic":false,"types":[]},{"text":"impl PartialEq<BorderType> for BorderType","synthetic":false,"types":[]},{"text":"impl PartialEq<Connectivity> for Connectivity","synthetic":false,"types":[]},{"text":"impl PartialEq<ConvMode> for ConvMode","synthetic":false,"types":[]},{"text":"impl PartialEq<ConvDomain> for ConvDomain","synthetic":false,"types":[]},{"text":"impl PartialEq<MatchType> for MatchType","synthetic":false,"types":[]},{"text":"impl PartialEq<ColorSpace> for ColorSpace","synthetic":false,"types":[]},{"text":"impl PartialEq<MatProp> for MatProp","synthetic":false,"types":[]},{"text":"impl PartialEq<NormType> for NormType","synthetic":false,"types":[]},{"text":"impl PartialEq<ColorMap> for ColorMap","synthetic":false,"types":[]},{"text":"impl PartialEq<YCCStd> for YCCStd","synthetic":false,"types":[]},{"text":"impl PartialEq<HomographyType> for HomographyType","synthetic":false,"types":[]},{"text":"impl PartialEq<MarkerType> for MarkerType","synthetic":false,"types":[]},{"text":"impl PartialEq<MomentType> for MomentType","synthetic":false,"types":[]},{"text":"impl PartialEq<SparseFormat> for SparseFormat","synthetic":false,"types":[]},{"text":"impl PartialEq<BinaryOp> for BinaryOp","synthetic":false,"types":[]},{"text":"impl PartialEq<RandomEngineType> for RandomEngineType","synthetic":false,"types":[]},{"text":"impl PartialEq<Scalar> for Scalar","synthetic":false,"types":[]},{"text":"impl PartialEq<CannyThresholdType> for CannyThresholdType","synthetic":false,"types":[]},{"text":"impl PartialEq<DiffusionEq> for DiffusionEq","synthetic":false,"types":[]},{"text":"impl PartialEq<FluxFn> for FluxFn","synthetic":false,"types":[]},{"text":"impl PartialEq<TopkFn> for TopkFn","synthetic":false,"types":[]},{"text":"impl PartialEq<IterativeDeconvAlgo> for IterativeDeconvAlgo","synthetic":false,"types":[]},{"text":"impl PartialEq<InverseDeconvAlgo> for InverseDeconvAlgo","synthetic":false,"types":[]},{"text":"impl PartialEq<ConvGradientType> for ConvGradientType","synthetic":false,"types":[]},{"text":"impl PartialEq<VarianceBias> for VarianceBias","synthetic":false,"types":[]},{"text":"impl PartialEq<CublasMathMode> for CublasMathMode","synthetic":false,"types":[]},{"text":"impl PartialEq<Dim4> for Dim4","synthetic":false,"types":[]},{"text":"impl<T: PartialEq + IndexableType> PartialEq<Seq<T>> for Seq<T>","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.From.js b/implementors/core/convert/trait.From.js new file mode 100644 index 000000000..481e145dc --- /dev/null +++ b/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl From<*mut c_void> for RandomEngine","synthetic":false,"types":[]},{"text":"impl From<i32> for AfError","synthetic":false,"types":[]},{"text":"impl From<u32> for DType","synthetic":false,"types":[]},{"text":"impl From<u32> for InterpType","synthetic":false,"types":[]},{"text":"impl From<u32> for ConvMode","synthetic":false,"types":[]},{"text":"impl From<u32> for ConvDomain","synthetic":false,"types":[]},{"text":"impl From<u32> for MatchType","synthetic":false,"types":[]},{"text":"impl From<u32> for ColorMap","synthetic":false,"types":[]},{"text":"impl From<u32> for SparseFormat","synthetic":false,"types":[]},{"text":"impl From<u32> for BinaryOp","synthetic":false,"types":[]},{"text":"impl From<u32> for RandomEngineType","synthetic":false,"types":[]},{"text":"impl From<u32> for MatProp","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.Into.js b/implementors/core/convert/trait.Into.js new file mode 100644 index 000000000..d13051c26 --- /dev/null +++ b/implementors/core/convert/trait.Into.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<T: HasAfEnum> Into<Array<T>> for af_array","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 000000000..b8ea2c535 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl Default for Dim4","synthetic":false,"types":[]},{"text":"impl Default for Event","synthetic":false,"types":[]},{"text":"impl<'object> Default for Indexer<'object>","synthetic":false,"types":[]},{"text":"impl<T> Default for Seq<T> where
    T: One + Zero + IndexableType, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 000000000..4ed6769d3 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Debug for VendorPlatform","synthetic":false,"types":[]},{"text":"impl Debug for DeviceType","synthetic":false,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl Debug for AfError","synthetic":false,"types":[]},{"text":"impl Debug for Backend","synthetic":false,"types":[]},{"text":"impl Debug for DType","synthetic":false,"types":[]},{"text":"impl Debug for InterpType","synthetic":false,"types":[]},{"text":"impl Debug for BorderType","synthetic":false,"types":[]},{"text":"impl Debug for Connectivity","synthetic":false,"types":[]},{"text":"impl Debug for ConvMode","synthetic":false,"types":[]},{"text":"impl Debug for ConvDomain","synthetic":false,"types":[]},{"text":"impl Debug for MatchType","synthetic":false,"types":[]},{"text":"impl Debug for ColorSpace","synthetic":false,"types":[]},{"text":"impl Debug for MatProp","synthetic":false,"types":[]},{"text":"impl Debug for NormType","synthetic":false,"types":[]},{"text":"impl Debug for ColorMap","synthetic":false,"types":[]},{"text":"impl Debug for YCCStd","synthetic":false,"types":[]},{"text":"impl Debug for HomographyType","synthetic":false,"types":[]},{"text":"impl Debug for MarkerType","synthetic":false,"types":[]},{"text":"impl Debug for MomentType","synthetic":false,"types":[]},{"text":"impl Debug for SparseFormat","synthetic":false,"types":[]},{"text":"impl Debug for BinaryOp","synthetic":false,"types":[]},{"text":"impl Debug for RandomEngineType","synthetic":false,"types":[]},{"text":"impl Debug for Scalar","synthetic":false,"types":[]},{"text":"impl Debug for CannyThresholdType","synthetic":false,"types":[]},{"text":"impl Debug for DiffusionEq","synthetic":false,"types":[]},{"text":"impl Debug for FluxFn","synthetic":false,"types":[]},{"text":"impl Debug for TopkFn","synthetic":false,"types":[]},{"text":"impl Debug for IterativeDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Debug for InverseDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Debug for ConvGradientType","synthetic":false,"types":[]},{"text":"impl Debug for VarianceBias","synthetic":false,"types":[]},{"text":"impl Debug for CublasMathMode","synthetic":false,"types":[]},{"text":"impl Debug for Dim4","synthetic":false,"types":[]},{"text":"impl<T: Debug + IndexableType> Debug for Seq<T>","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Display.js b/implementors/core/fmt/trait.Display.js new file mode 100644 index 000000000..bae7d241e --- /dev/null +++ b/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl Display for Backend","synthetic":false,"types":[]},{"text":"impl Display for AfError","synthetic":false,"types":[]},{"text":"impl Display for Dim4","synthetic":false,"types":[]},{"text":"impl<T> Display for Seq<T> where
    T: Display + IndexableType, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Copy.js b/implementors/core/marker/trait.Copy.js new file mode 100644 index 000000000..1a482d080 --- /dev/null +++ b/implementors/core/marker/trait.Copy.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Copy for VendorPlatform","synthetic":false,"types":[]},{"text":"impl Copy for DeviceType","synthetic":false,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl Copy for AfError","synthetic":false,"types":[]},{"text":"impl Copy for Backend","synthetic":false,"types":[]},{"text":"impl Copy for DType","synthetic":false,"types":[]},{"text":"impl Copy for InterpType","synthetic":false,"types":[]},{"text":"impl Copy for BorderType","synthetic":false,"types":[]},{"text":"impl Copy for Connectivity","synthetic":false,"types":[]},{"text":"impl Copy for ConvMode","synthetic":false,"types":[]},{"text":"impl Copy for ConvDomain","synthetic":false,"types":[]},{"text":"impl Copy for MatchType","synthetic":false,"types":[]},{"text":"impl Copy for ColorSpace","synthetic":false,"types":[]},{"text":"impl Copy for MatProp","synthetic":false,"types":[]},{"text":"impl Copy for NormType","synthetic":false,"types":[]},{"text":"impl Copy for ColorMap","synthetic":false,"types":[]},{"text":"impl Copy for YCCStd","synthetic":false,"types":[]},{"text":"impl Copy for HomographyType","synthetic":false,"types":[]},{"text":"impl Copy for MarkerType","synthetic":false,"types":[]},{"text":"impl Copy for MomentType","synthetic":false,"types":[]},{"text":"impl Copy for SparseFormat","synthetic":false,"types":[]},{"text":"impl Copy for BinaryOp","synthetic":false,"types":[]},{"text":"impl Copy for RandomEngineType","synthetic":false,"types":[]},{"text":"impl Copy for Scalar","synthetic":false,"types":[]},{"text":"impl Copy for CannyThresholdType","synthetic":false,"types":[]},{"text":"impl Copy for DiffusionEq","synthetic":false,"types":[]},{"text":"impl Copy for FluxFn","synthetic":false,"types":[]},{"text":"impl Copy for TopkFn","synthetic":false,"types":[]},{"text":"impl Copy for IterativeDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Copy for InverseDeconvAlgo","synthetic":false,"types":[]},{"text":"impl Copy for ConvGradientType","synthetic":false,"types":[]},{"text":"impl Copy for VarianceBias","synthetic":false,"types":[]},{"text":"impl Copy for CublasMathMode","synthetic":false,"types":[]},{"text":"impl Copy for Dim4","synthetic":false,"types":[]},{"text":"impl<T: Copy + IndexableType> Copy for Seq<T>","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 000000000..714a5c465 --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Freeze for VendorPlatform","synthetic":true,"types":[]},{"text":"impl Freeze for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl<T> Freeze for Array<T>","synthetic":true,"types":[]},{"text":"impl Freeze for Dim4","synthetic":true,"types":[]},{"text":"impl Freeze for Callback","synthetic":true,"types":[]},{"text":"impl Freeze for Event","synthetic":true,"types":[]},{"text":"impl<'object> Freeze for Indexer<'object>","synthetic":true,"types":[]},{"text":"impl Freeze for RandomEngine","synthetic":true,"types":[]},{"text":"impl<T> Freeze for Seq<T> where
    T: Freeze, 
","synthetic":true,"types":[]},{"text":"impl Freeze for Window","synthetic":true,"types":[]},{"text":"impl Freeze for Features","synthetic":true,"types":[]},{"text":"impl Freeze for AfError","synthetic":true,"types":[]},{"text":"impl Freeze for Backend","synthetic":true,"types":[]},{"text":"impl Freeze for DType","synthetic":true,"types":[]},{"text":"impl Freeze for InterpType","synthetic":true,"types":[]},{"text":"impl Freeze for BorderType","synthetic":true,"types":[]},{"text":"impl Freeze for Connectivity","synthetic":true,"types":[]},{"text":"impl Freeze for ConvMode","synthetic":true,"types":[]},{"text":"impl Freeze for ConvDomain","synthetic":true,"types":[]},{"text":"impl Freeze for MatchType","synthetic":true,"types":[]},{"text":"impl Freeze for ColorSpace","synthetic":true,"types":[]},{"text":"impl Freeze for MatProp","synthetic":true,"types":[]},{"text":"impl Freeze for NormType","synthetic":true,"types":[]},{"text":"impl Freeze for ColorMap","synthetic":true,"types":[]},{"text":"impl Freeze for YCCStd","synthetic":true,"types":[]},{"text":"impl Freeze for HomographyType","synthetic":true,"types":[]},{"text":"impl Freeze for MarkerType","synthetic":true,"types":[]},{"text":"impl Freeze for MomentType","synthetic":true,"types":[]},{"text":"impl Freeze for SparseFormat","synthetic":true,"types":[]},{"text":"impl Freeze for BinaryOp","synthetic":true,"types":[]},{"text":"impl Freeze for RandomEngineType","synthetic":true,"types":[]},{"text":"impl Freeze for Scalar","synthetic":true,"types":[]},{"text":"impl Freeze for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl Freeze for DiffusionEq","synthetic":true,"types":[]},{"text":"impl Freeze for FluxFn","synthetic":true,"types":[]},{"text":"impl Freeze for TopkFn","synthetic":true,"types":[]},{"text":"impl Freeze for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Freeze for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Freeze for ConvGradientType","synthetic":true,"types":[]},{"text":"impl Freeze for VarianceBias","synthetic":true,"types":[]},{"text":"impl Freeze for CublasMathMode","synthetic":true,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 000000000..30e68a3e5 --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Send for VendorPlatform","synthetic":true,"types":[]},{"text":"impl Send for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl Send for Dim4","synthetic":true,"types":[]},{"text":"impl Send for Callback","synthetic":true,"types":[]},{"text":"impl<T> Send for Seq<T> where
    T: Send, 
","synthetic":true,"types":[]},{"text":"impl !Send for Window","synthetic":true,"types":[]},{"text":"impl Send for AfError","synthetic":true,"types":[]},{"text":"impl Send for Backend","synthetic":true,"types":[]},{"text":"impl Send for DType","synthetic":true,"types":[]},{"text":"impl Send for InterpType","synthetic":true,"types":[]},{"text":"impl Send for BorderType","synthetic":true,"types":[]},{"text":"impl Send for Connectivity","synthetic":true,"types":[]},{"text":"impl Send for ConvMode","synthetic":true,"types":[]},{"text":"impl Send for ConvDomain","synthetic":true,"types":[]},{"text":"impl Send for MatchType","synthetic":true,"types":[]},{"text":"impl Send for ColorSpace","synthetic":true,"types":[]},{"text":"impl Send for MatProp","synthetic":true,"types":[]},{"text":"impl Send for NormType","synthetic":true,"types":[]},{"text":"impl Send for ColorMap","synthetic":true,"types":[]},{"text":"impl Send for YCCStd","synthetic":true,"types":[]},{"text":"impl Send for HomographyType","synthetic":true,"types":[]},{"text":"impl Send for MarkerType","synthetic":true,"types":[]},{"text":"impl Send for MomentType","synthetic":true,"types":[]},{"text":"impl Send for SparseFormat","synthetic":true,"types":[]},{"text":"impl Send for BinaryOp","synthetic":true,"types":[]},{"text":"impl Send for RandomEngineType","synthetic":true,"types":[]},{"text":"impl Send for Scalar","synthetic":true,"types":[]},{"text":"impl Send for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl Send for DiffusionEq","synthetic":true,"types":[]},{"text":"impl Send for FluxFn","synthetic":true,"types":[]},{"text":"impl Send for TopkFn","synthetic":true,"types":[]},{"text":"impl Send for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Send for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Send for ConvGradientType","synthetic":true,"types":[]},{"text":"impl Send for VarianceBias","synthetic":true,"types":[]},{"text":"impl Send for CublasMathMode","synthetic":true,"types":[]},{"text":"impl<T: HasAfEnum> Send for Array<T>","synthetic":false,"types":[]},{"text":"impl Send for Event","synthetic":false,"types":[]},{"text":"impl<'object> Send for Indexer<'object>","synthetic":false,"types":[]},{"text":"impl Send for RandomEngine","synthetic":false,"types":[]},{"text":"impl Send for Features","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralPartialEq.js b/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 000000000..6f3f52418 --- /dev/null +++ b/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl StructuralPartialEq for VendorPlatform","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for DeviceType","synthetic":false,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl StructuralPartialEq for AfError","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for Backend","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for DType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for InterpType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for BorderType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for Connectivity","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for ConvMode","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for ConvDomain","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for MatchType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for ColorSpace","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for MatProp","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for NormType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for ColorMap","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for YCCStd","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for HomographyType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for MarkerType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for MomentType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for SparseFormat","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for BinaryOp","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for RandomEngineType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for Scalar","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for CannyThresholdType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for DiffusionEq","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for FluxFn","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for TopkFn","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for IterativeDeconvAlgo","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for InverseDeconvAlgo","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for ConvGradientType","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for VarianceBias","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for CublasMathMode","synthetic":false,"types":[]},{"text":"impl StructuralPartialEq for Dim4","synthetic":false,"types":[]},{"text":"impl<T: IndexableType> StructuralPartialEq for Seq<T>","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 000000000..c73baefcb --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Sync for VendorPlatform","synthetic":true,"types":[]},{"text":"impl Sync for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl Sync for Dim4","synthetic":true,"types":[]},{"text":"impl Sync for Callback","synthetic":true,"types":[]},{"text":"impl !Sync for Event","synthetic":true,"types":[]},{"text":"impl<'object> !Sync for Indexer<'object>","synthetic":true,"types":[]},{"text":"impl !Sync for RandomEngine","synthetic":true,"types":[]},{"text":"impl<T> Sync for Seq<T> where
    T: Sync, 
","synthetic":true,"types":[]},{"text":"impl !Sync for Window","synthetic":true,"types":[]},{"text":"impl Sync for AfError","synthetic":true,"types":[]},{"text":"impl Sync for Backend","synthetic":true,"types":[]},{"text":"impl Sync for DType","synthetic":true,"types":[]},{"text":"impl Sync for InterpType","synthetic":true,"types":[]},{"text":"impl Sync for BorderType","synthetic":true,"types":[]},{"text":"impl Sync for Connectivity","synthetic":true,"types":[]},{"text":"impl Sync for ConvMode","synthetic":true,"types":[]},{"text":"impl Sync for ConvDomain","synthetic":true,"types":[]},{"text":"impl Sync for MatchType","synthetic":true,"types":[]},{"text":"impl Sync for ColorSpace","synthetic":true,"types":[]},{"text":"impl Sync for MatProp","synthetic":true,"types":[]},{"text":"impl Sync for NormType","synthetic":true,"types":[]},{"text":"impl Sync for ColorMap","synthetic":true,"types":[]},{"text":"impl Sync for YCCStd","synthetic":true,"types":[]},{"text":"impl Sync for HomographyType","synthetic":true,"types":[]},{"text":"impl Sync for MarkerType","synthetic":true,"types":[]},{"text":"impl Sync for MomentType","synthetic":true,"types":[]},{"text":"impl Sync for SparseFormat","synthetic":true,"types":[]},{"text":"impl Sync for BinaryOp","synthetic":true,"types":[]},{"text":"impl Sync for RandomEngineType","synthetic":true,"types":[]},{"text":"impl Sync for Scalar","synthetic":true,"types":[]},{"text":"impl Sync for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl Sync for DiffusionEq","synthetic":true,"types":[]},{"text":"impl Sync for FluxFn","synthetic":true,"types":[]},{"text":"impl Sync for TopkFn","synthetic":true,"types":[]},{"text":"impl Sync for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Sync for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Sync for ConvGradientType","synthetic":true,"types":[]},{"text":"impl Sync for VarianceBias","synthetic":true,"types":[]},{"text":"impl Sync for CublasMathMode","synthetic":true,"types":[]},{"text":"impl<T: HasAfEnum> Sync for Array<T>","synthetic":false,"types":[]},{"text":"impl Sync for Features","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 000000000..841cb4dda --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl Unpin for VendorPlatform","synthetic":true,"types":[]},{"text":"impl Unpin for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl<T> Unpin for Array<T> where
    T: Unpin, 
","synthetic":true,"types":[]},{"text":"impl Unpin for Dim4","synthetic":true,"types":[]},{"text":"impl Unpin for Callback","synthetic":true,"types":[]},{"text":"impl Unpin for Event","synthetic":true,"types":[]},{"text":"impl<'object> Unpin for Indexer<'object>","synthetic":true,"types":[]},{"text":"impl Unpin for RandomEngine","synthetic":true,"types":[]},{"text":"impl<T> Unpin for Seq<T> where
    T: Unpin, 
","synthetic":true,"types":[]},{"text":"impl Unpin for Window","synthetic":true,"types":[]},{"text":"impl Unpin for Features","synthetic":true,"types":[]},{"text":"impl Unpin for AfError","synthetic":true,"types":[]},{"text":"impl Unpin for Backend","synthetic":true,"types":[]},{"text":"impl Unpin for DType","synthetic":true,"types":[]},{"text":"impl Unpin for InterpType","synthetic":true,"types":[]},{"text":"impl Unpin for BorderType","synthetic":true,"types":[]},{"text":"impl Unpin for Connectivity","synthetic":true,"types":[]},{"text":"impl Unpin for ConvMode","synthetic":true,"types":[]},{"text":"impl Unpin for ConvDomain","synthetic":true,"types":[]},{"text":"impl Unpin for MatchType","synthetic":true,"types":[]},{"text":"impl Unpin for ColorSpace","synthetic":true,"types":[]},{"text":"impl Unpin for MatProp","synthetic":true,"types":[]},{"text":"impl Unpin for NormType","synthetic":true,"types":[]},{"text":"impl Unpin for ColorMap","synthetic":true,"types":[]},{"text":"impl Unpin for YCCStd","synthetic":true,"types":[]},{"text":"impl Unpin for HomographyType","synthetic":true,"types":[]},{"text":"impl Unpin for MarkerType","synthetic":true,"types":[]},{"text":"impl Unpin for MomentType","synthetic":true,"types":[]},{"text":"impl Unpin for SparseFormat","synthetic":true,"types":[]},{"text":"impl Unpin for BinaryOp","synthetic":true,"types":[]},{"text":"impl Unpin for RandomEngineType","synthetic":true,"types":[]},{"text":"impl Unpin for Scalar","synthetic":true,"types":[]},{"text":"impl Unpin for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl Unpin for DiffusionEq","synthetic":true,"types":[]},{"text":"impl Unpin for FluxFn","synthetic":true,"types":[]},{"text":"impl Unpin for TopkFn","synthetic":true,"types":[]},{"text":"impl Unpin for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Unpin for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl Unpin for ConvGradientType","synthetic":true,"types":[]},{"text":"impl Unpin for VarianceBias","synthetic":true,"types":[]},{"text":"impl Unpin for CublasMathMode","synthetic":true,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Add.js b/implementors/core/ops/arith/trait.Add.js new file mode 100644 index 000000000..794aa7885 --- /dev/null +++ b/implementors/core/ops/arith/trait.Add.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<'f, T, U> Add<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<T, U> Add<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Add<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Add<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<A, B> Add<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Add<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Add<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Add<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.AddAssign.js b/implementors/core/ops/arith/trait.AddAssign.js new file mode 100644 index 000000000..443d4fd37 --- /dev/null +++ b/implementors/core/ops/arith/trait.AddAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> AddAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Div.js b/implementors/core/ops/arith/trait.Div.js new file mode 100644 index 000000000..5988a5be8 --- /dev/null +++ b/implementors/core/ops/arith/trait.Div.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<'f, T, U> Div<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<T, U> Div<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Div<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Div<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<A, B> Div<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Div<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Div<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Div<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.DivAssign.js b/implementors/core/ops/arith/trait.DivAssign.js new file mode 100644 index 000000000..634626076 --- /dev/null +++ b/implementors/core/ops/arith/trait.DivAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> DivAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Mul.js b/implementors/core/ops/arith/trait.Mul.js new file mode 100644 index 000000000..2723c394e --- /dev/null +++ b/implementors/core/ops/arith/trait.Mul.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<'f, T, U> Mul<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<T, U> Mul<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Mul<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Mul<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<A, B> Mul<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Mul<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Mul<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Mul<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.MulAssign.js b/implementors/core/ops/arith/trait.MulAssign.js new file mode 100644 index 000000000..02d271741 --- /dev/null +++ b/implementors/core/ops/arith/trait.MulAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> MulAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Neg.js b/implementors/core/ops/arith/trait.Neg.js new file mode 100644 index 000000000..c3e679bcb --- /dev/null +++ b/implementors/core/ops/arith/trait.Neg.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<T> Neg for Array<T> where
    T: Zero + ConstGenerator<OutType = T>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Rem.js b/implementors/core/ops/arith/trait.Rem.js new file mode 100644 index 000000000..c39824b0b --- /dev/null +++ b/implementors/core/ops/arith/trait.Rem.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> Rem<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Rem<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Rem<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Rem<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.RemAssign.js b/implementors/core/ops/arith/trait.RemAssign.js new file mode 100644 index 000000000..dacbaeeac --- /dev/null +++ b/implementors/core/ops/arith/trait.RemAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> RemAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.Sub.js b/implementors/core/ops/arith/trait.Sub.js new file mode 100644 index 000000000..293a3117b --- /dev/null +++ b/implementors/core/ops/arith/trait.Sub.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<'f, T, U> Sub<U> for &'f Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<T, U> Sub<U> for Array<T> where
    T: ImplicitPromote<U>,
    U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for Complex<f64> where
    T: ImplicitPromote<Complex<f64>>,
    Complex<f64>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for Complex<f32> where
    T: ImplicitPromote<Complex<f32>>,
    Complex<f32>: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for f64 where
    T: ImplicitPromote<f64>,
    f64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for f32 where
    T: ImplicitPromote<f32>,
    f32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for u64 where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for i64 where
    T: ImplicitPromote<i64>,
    i64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for u32 where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for i32 where
    T: ImplicitPromote<i32>,
    i32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Sub<&'f Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Sub<Array<T>> for u8 where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<A, B> Sub<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Sub<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Sub<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Sub<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/arith/trait.SubAssign.js b/implementors/core/ops/arith/trait.SubAssign.js new file mode 100644 index 000000000..cc582b9c8 --- /dev/null +++ b/implementors/core/ops/arith/trait.SubAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> SubAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitAnd.js b/implementors/core/ops/bit/trait.BitAnd.js new file mode 100644 index 000000000..33c322327 --- /dev/null +++ b/implementors/core/ops/bit/trait.BitAnd.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitAnd<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitAnd<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitAnd<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> BitAnd<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitAndAssign.js b/implementors/core/ops/bit/trait.BitAndAssign.js new file mode 100644 index 000000000..6ffc7b355 --- /dev/null +++ b/implementors/core/ops/bit/trait.BitAndAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitAndAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitOr.js b/implementors/core/ops/bit/trait.BitOr.js new file mode 100644 index 000000000..ca03a8c1f --- /dev/null +++ b/implementors/core/ops/bit/trait.BitOr.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitOr<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitOr<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitOr<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> BitOr<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl BitOr<MatProp> for MatProp","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitOrAssign.js b/implementors/core/ops/bit/trait.BitOrAssign.js new file mode 100644 index 000000000..c7cdbeff7 --- /dev/null +++ b/implementors/core/ops/bit/trait.BitOrAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitOrAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitXor.js b/implementors/core/ops/bit/trait.BitXor.js new file mode 100644 index 000000000..b470c9d01 --- /dev/null +++ b/implementors/core/ops/bit/trait.BitXor.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitXor<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitXor<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> BitXor<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> BitXor<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.BitXorAssign.js b/implementors/core/ops/bit/trait.BitXorAssign.js new file mode 100644 index 000000000..538612a9a --- /dev/null +++ b/implementors/core/ops/bit/trait.BitXorAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> BitXorAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.Not.js b/implementors/core/ops/bit/trait.Not.js new file mode 100644 index 000000000..5e44dc552 --- /dev/null +++ b/implementors/core/ops/bit/trait.Not.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<'f, T> Not for &'f Array<T> where
    T: HasAfEnum, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.Shl.js b/implementors/core/ops/bit/trait.Shl.js new file mode 100644 index 000000000..3ed88c642 --- /dev/null +++ b/implementors/core/ops/bit/trait.Shl.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> Shl<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Shl<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Shl<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Shl<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shl<u64> for Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shl<u64> for &'f Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shl<u32> for Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shl<u32> for &'f Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shl<u16> for Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shl<u16> for &'f Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shl<u8> for Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shl<u8> for &'f Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.ShlAssign.js b/implementors/core/ops/bit/trait.ShlAssign.js new file mode 100644 index 000000000..9531d9f5d --- /dev/null +++ b/implementors/core/ops/bit/trait.ShlAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> ShlAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShlAssign<u64> for Array<T> where
    u64: ImplicitPromote<T>,
    T: ImplicitPromote<u64, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShlAssign<u32> for Array<T> where
    u32: ImplicitPromote<T>,
    T: ImplicitPromote<u32, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShlAssign<u16> for Array<T> where
    u16: ImplicitPromote<T>,
    T: ImplicitPromote<u16, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShlAssign<u8> for Array<T> where
    u8: ImplicitPromote<T>,
    T: ImplicitPromote<u8, Output = T>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.Shr.js b/implementors/core/ops/bit/trait.Shr.js new file mode 100644 index 000000000..4e781e593 --- /dev/null +++ b/implementors/core/ops/bit/trait.Shr.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> Shr<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Shr<&'a Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, A, B> Shr<Array<B>> for &'a Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<'a, 'b, A, B> Shr<&'a Array<B>> for &'b Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shr<u64> for Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shr<u64> for &'f Array<T> where
    T: ImplicitPromote<u64>,
    u64: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shr<u32> for Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shr<u32> for &'f Array<T> where
    T: ImplicitPromote<u32>,
    u32: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shr<u16> for Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shr<u16> for &'f Array<T> where
    T: ImplicitPromote<u16>,
    u16: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<T> Shr<u8> for Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]},{"text":"impl<'f, T> Shr<u8> for &'f Array<T> where
    T: ImplicitPromote<u8>,
    u8: ImplicitPromote<T>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/bit/trait.ShrAssign.js b/implementors/core/ops/bit/trait.ShrAssign.js new file mode 100644 index 000000000..18cd1a82e --- /dev/null +++ b/implementors/core/ops/bit/trait.ShrAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<A, B> ShrAssign<Array<B>> for Array<A> where
    A: ImplicitPromote<B>,
    B: ImplicitPromote<A>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShrAssign<u64> for Array<T> where
    u64: ImplicitPromote<T>,
    T: ImplicitPromote<u64, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShrAssign<u32> for Array<T> where
    u32: ImplicitPromote<T>,
    T: ImplicitPromote<u32, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShrAssign<u16> for Array<T> where
    u16: ImplicitPromote<T>,
    T: ImplicitPromote<u16, Output = T>, 
","synthetic":false,"types":[]},{"text":"impl<T> ShrAssign<u8> for Array<T> where
    u8: ImplicitPromote<T>,
    T: ImplicitPromote<u8, Output = T>, 
","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/drop/trait.Drop.js b/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 000000000..e1c06fc1e --- /dev/null +++ b/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl<T> Drop for Array<T> where
    T: HasAfEnum, 
","synthetic":false,"types":[]},{"text":"impl Drop for Event","synthetic":false,"types":[]},{"text":"impl<'object> Drop for Indexer<'object>","synthetic":false,"types":[]},{"text":"impl Drop for RandomEngine","synthetic":false,"types":[]},{"text":"impl Drop for Window","synthetic":false,"types":[]},{"text":"impl Drop for Features","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.Index.js b/implementors/core/ops/index/trait.Index.js new file mode 100644 index 000000000..33c4b88ab --- /dev/null +++ b/implementors/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl Index<usize> for Dim4","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.IndexMut.js b/implementors/core/ops/index/trait.IndexMut.js new file mode 100644 index 000000000..de6c28781 --- /dev/null +++ b/implementors/core/ops/index/trait.IndexMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["arrayfire"] = [{"text":"impl IndexMut<usize> for Dim4","synthetic":false,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.RefUnwindSafe.js b/implementors/std/panic/trait.RefUnwindSafe.js new file mode 100644 index 000000000..643078b56 --- /dev/null +++ b/implementors/std/panic/trait.RefUnwindSafe.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl RefUnwindSafe for VendorPlatform","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl<T> RefUnwindSafe for Array<T> where
    T: RefUnwindSafe, 
","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Dim4","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Callback","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Event","synthetic":true,"types":[]},{"text":"impl<'object> RefUnwindSafe for Indexer<'object>","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for RandomEngine","synthetic":true,"types":[]},{"text":"impl<T> RefUnwindSafe for Seq<T> where
    T: RefUnwindSafe, 
","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Window","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Features","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for AfError","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Backend","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for DType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for InterpType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for BorderType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Connectivity","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for ConvMode","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for ConvDomain","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for MatchType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for ColorSpace","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for MatProp","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for NormType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for ColorMap","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for YCCStd","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for HomographyType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for MarkerType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for MomentType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for SparseFormat","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for BinaryOp","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for RandomEngineType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for Scalar","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for DiffusionEq","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for FluxFn","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for TopkFn","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for ConvGradientType","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for VarianceBias","synthetic":true,"types":[]},{"text":"impl RefUnwindSafe for CublasMathMode","synthetic":true,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.UnwindSafe.js b/implementors/std/panic/trait.UnwindSafe.js new file mode 100644 index 000000000..60ebf01c9 --- /dev/null +++ b/implementors/std/panic/trait.UnwindSafe.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["af_opencl_interop"] = [{"text":"impl UnwindSafe for VendorPlatform","synthetic":true,"types":[]},{"text":"impl UnwindSafe for DeviceType","synthetic":true,"types":[]}]; +implementors["arrayfire"] = [{"text":"impl<T> UnwindSafe for Array<T> where
    T: UnwindSafe, 
","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Dim4","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Callback","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Event","synthetic":true,"types":[]},{"text":"impl<'object> UnwindSafe for Indexer<'object>","synthetic":true,"types":[]},{"text":"impl UnwindSafe for RandomEngine","synthetic":true,"types":[]},{"text":"impl<T> UnwindSafe for Seq<T> where
    T: UnwindSafe, 
","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Window","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Features","synthetic":true,"types":[]},{"text":"impl UnwindSafe for AfError","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Backend","synthetic":true,"types":[]},{"text":"impl UnwindSafe for DType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for InterpType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for BorderType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Connectivity","synthetic":true,"types":[]},{"text":"impl UnwindSafe for ConvMode","synthetic":true,"types":[]},{"text":"impl UnwindSafe for ConvDomain","synthetic":true,"types":[]},{"text":"impl UnwindSafe for MatchType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for ColorSpace","synthetic":true,"types":[]},{"text":"impl UnwindSafe for MatProp","synthetic":true,"types":[]},{"text":"impl UnwindSafe for NormType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for ColorMap","synthetic":true,"types":[]},{"text":"impl UnwindSafe for YCCStd","synthetic":true,"types":[]},{"text":"impl UnwindSafe for HomographyType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for MarkerType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for MomentType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for SparseFormat","synthetic":true,"types":[]},{"text":"impl UnwindSafe for BinaryOp","synthetic":true,"types":[]},{"text":"impl UnwindSafe for RandomEngineType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for Scalar","synthetic":true,"types":[]},{"text":"impl UnwindSafe for CannyThresholdType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for DiffusionEq","synthetic":true,"types":[]},{"text":"impl UnwindSafe for FluxFn","synthetic":true,"types":[]},{"text":"impl UnwindSafe for TopkFn","synthetic":true,"types":[]},{"text":"impl UnwindSafe for IterativeDeconvAlgo","synthetic":true,"types":[]},{"text":"impl UnwindSafe for InverseDeconvAlgo","synthetic":true,"types":[]},{"text":"impl UnwindSafe for ConvGradientType","synthetic":true,"types":[]},{"text":"impl UnwindSafe for VarianceBias","synthetic":true,"types":[]},{"text":"impl UnwindSafe for CublasMathMode","synthetic":true,"types":[]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/light.css b/light.css new file mode 100644 index 000000000..6ec01d671 --- /dev/null +++ b/light.css @@ -0,0 +1 @@ + body{background-color:white;color:black;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:black;}h1.fqn{border-bottom-color:#D5D5D5;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#DDDDDD;}.in-band{background-color:white;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#F5F5F5;}pre{background-color:#F5F5F5;}.sidebar{background-color:#F1F1F1;}*{scrollbar-color:rgba(36,37,39,0.6) #e6e6e6;}.sidebar{scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;}.logo-container.rust-logo>img{}::-webkit-scrollbar-track{background-color:#ecebeb;}::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar::-webkit-scrollbar-track{background-color:#dcdcdc;}.sidebar::-webkit-scrollbar-thumb{background-color:rgba(36,37,39,0.6);}.sidebar .current{background-color:#fff;}.source .sidebar{background-color:#fff;}.sidebar .location{border-color:#000;background-color:#fff;color:#333;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.content span.fn,.content a.fn,.block a.current.fn,.content span.method,.content a.method,.block a.current.method,.content span.tymethod,.content a.tymethod,.block a.current.tymethod,.content .fnname{color:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav:not(.sidebar){border-bottom-color:#e0e0e0;}nav.main .current{border-top-color:#000;border-bottom-color:#000;}nav.main .separator{border:1px solid #000;}a{color:#000;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a,#help a{color:#3873AD;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}.search-focus:disabled{background-color:#e6e6e6;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{color:#000;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}#help>div>span{border-bottom-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#8959A8;}pre.rust .kw-2,pre.rust .prelude-ty{color:#4271AE;}pre.rust .number,pre.rust .string{color:#718C00;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#C82829;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#B76514;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;border-right:3px solid #ffb44c;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.5);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.should_panic{border-left:2px solid rgba(255,0,0,.5);}pre.should_panic:hover,.information:hover+pre.should_panic{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.5);}.information>.compile_fail:hover{color:#f00;}.tooltip.should_panic{color:rgba(255,0,0,.5);}.information>.should_panic:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:#ff9200;}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:#000;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}.notable-traits-tooltiptext{background-color:#eee;border-color:#999;}#titles>div:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu,.help-button{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus,.help-button:hover,.help-button:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 000000000..2f8b881b8 --- /dev/null +++ b/main.js @@ -0,0 +1,8 @@ +if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position}}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1}}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className}else{this.className=className}}}}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim()}}}function getSearchInput(){return document.getElementsByClassName("search-input")[0]}function getSearchElement(){return document.getElementById("search")}function getThemesElement(){return document.getElementById("theme-choices")}function getThemePickerElement(){return document.getElementById("theme-picker")}function focusSearchBar(){getSearchInput().focus()}function defocusSearchBar(){getSearchInput().blur()}(function(){"use strict";var itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias"];var disableShortcuts=getSettingValue("disable-shortcuts")==="true";var search_input=getSearchInput();var searchTimeout=null;var toggleAllDocsId="toggle-all-docs";var currentTab=0;var mouseMovedAfterSearch=true;var titleBeforeSearch=document.title;var searchTitle=null;function clearInputTimeout(){if(searchTimeout!==null){clearTimeout(searchTimeout);searchTimeout=null}}function getPageId(){if(window.location.hash){var tmp=window.location.hash.replace(/^#/,"");if(tmp.length>0){return tmp}}return null}function showSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){addClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];if(sidebar){addClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(!filler){var div=document.createElement("div");div.id="sidebar-filler";sidebar.appendChild(div)}}}function hideSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){removeClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(filler){filler.remove()}document.getElementsByTagName("body")[0].style.marginTop=""}function showSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(main,"hidden");removeClass(search,"hidden");mouseMovedAfterSearch=false;document.title=searchTitle}function hideSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(search,"hidden");removeClass(main,"hidden");document.title=titleBeforeSearch}var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");function getQueryStringParams(){var params={};window.location.search.substring(1).split("&").map(function(s){var pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function isHidden(elem){return elem.offsetHeight===0}var main=document.getElementById("main");var savedHash="";function handleHashes(ev){var elem;var search=getSearchElement();if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){hideSearchResults(search);var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(hash,"","?search=#"+hash)}elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}elem=document.getElementById(savedHash.slice(1));if(!elem||!isHidden(elem)){return}var parent=elem.parentNode;if(parent&&hasClass(parent,"impl-items")){onEachLazy(parent.getElementsByClassName("collapsed"),function(e){if(e.parentNode===parent){e.click();return true}});if(isHidden(elem)){if(hasClass(parent.lastElementChild,"collapse-toggle")){parent.lastElementChild.click()}}}}}function highlightSourceLines(match,ev){if(typeof match==="undefined"){hideSidebar();match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/)}if(!match){return}var from=parseInt(match[1],10);var to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to0){collapseDocs(collapses[0],"show")}}}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!="undefined"){return ev.key}var c=ev.charCode||ev.keyCode;if(c==27){return"Escape"}return String.fromCharCode(c)}function getHelpElement(){buildHelperPopup();return document.getElementById("help")}function displayHelp(display,ev,help){help=help?help:getHelpElement();if(display===true){if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur")}}else if(hasClass(help,"hidden")===false){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur")}}function handleEscape(ev){var help=getHelpElement();var search=getSearchElement();if(hasClass(help,"hidden")===false){displayHelp(false,ev,help)}else if(hasClass(search,"hidden")===false){clearInputTimeout();ev.preventDefault();hideSearchResults(search)}defocusSearchBar();hideThemeButtonState()}function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts===true){return}if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":displayHelp(false,ev);ev.preventDefault();focusSearchBar();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":displayHelp(true,ev);break;case"t":case"T":displayHelp(false,ev);ev.preventDefault();var themePicker=getThemePickerElement();themePicker.click();themePicker.focus();break;default:var themePicker=getThemePickerElement();if(themePicker.parentNode.contains(ev.target)){handleThemeKeyDown(ev)}}}}function handleThemeKeyDown(ev){var active=document.activeElement;var themes=getThemesElement();switch(getVirtualKey(ev)){case"ArrowUp":ev.preventDefault();if(active.previousElementSibling&&ev.target.id!=="theme-picker"){active.previousElementSibling.focus()}else{showThemeButtonState();themes.lastElementChild.focus()}break;case"ArrowDown":ev.preventDefault();if(active.nextElementSibling&&ev.target.id!=="theme-picker"){active.nextElementSibling.focus()}else{showThemeButtonState();themes.firstElementChild.focus()}break;case"Enter":case"Return":case"Space":if(ev.target.id==="theme-picker"&&themes.style.display==="none"){ev.preventDefault();showThemeButtonState();themes.firstElementChild.focus()}break;case"Home":ev.preventDefault();themes.firstElementChild.focus();break;case"End":ev.preventDefault();themes.lastElementChild.focus();break}}function findParentElement(elem,tagName){do{if(elem&&elem.tagName===tagName){return elem}elem=elem.parentNode}while(elem);return null}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function resetMouseMoved(ev){mouseMovedAfterSearch=true}document.addEventListener("mousemove",resetMouseMoved);var handleSourceHighlight=(function(){var prev_line_id=0;var set_fragment=function(name){var x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return function(ev){var cur_line_id=parseInt(ev.target.id,10);ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){var tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());document.addEventListener("click",function(ev){if(hasClass(ev.target,"help-button")){displayHelp(true,ev)}else if(hasClass(ev.target,"collapse-toggle")){collapseDocs(ev.target,"toggle")}else if(hasClass(ev.target.parentNode,"collapse-toggle")){collapseDocs(ev.target.parentNode,"toggle")}else if(ev.target.tagName==="SPAN"&&hasClass(ev.target.parentNode,"line-numbers")){handleSourceHighlight(ev)}else if(hasClass(getHelpElement(),"hidden")===false){var help=getHelpElement();var is_inside_help_popup=ev.target!==help&&help.contains(ev.target);if(is_inside_help_popup===false){addClass(help,"hidden");removeClass(document.body,"blur")}}else{var a=findParentElement(ev.target,"A");if(a&&a.hash){expandSection(a.hash.replace(/^#/,""))}}});(function(){var x=document.getElementsByClassName("version-selector");if(x.length>0){x[0].onchange=function(){var i,match,url=document.location.href,stripped="",len=rootPath.match(/\.\.\//g).length+1;for(i=0;i-1){var obj=searchIndex[results[i].id];obj.lev=results[i].lev;if(isType!==true||obj.type){var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}}return out}function sortResults(results,isType){var ar=[];for(var entry in results){if(hasOwnProperty(results,entry)){ar.push(results[entry])}}results=ar;var i;var nresults=results.length;for(i=0;ib?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});var length=results.length;for(i=0;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),}}return{name:val,generics:[],}}function getObjectFromId(id){if(typeof id==="number"){return searchIndex[id]}return{'name':id}}function checkGenerics(obj,val){var lev_distance=MAX_LEV_DISTANCE+1;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var total=0;var done=0;var vlength=val.generics.length;for(var y=0;yGENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var allFound=true;for(var y=0;allFound===true&&yGENERICS_DATA&&obj[GENERICS_DATA].length!==0){var tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev}}else{return 0}}if(literalSearch===true){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var length=obj[GENERICS_DATA].length;for(x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length>0){var olength=obj[GENERICS_DATA].length;for(x=0;x0){var length=obj.type[INPUTS_DATA].length;for(var i=0;iOUTPUT_DATA){var ret=obj.type[OUTPUT_DATA];if(typeof ret[0]==="string"){ret=[ret]}for(var x=0;xlength){return MAX_LEV_DISTANCE+1}for(var i=0;ilength){break}var lev_total=0;var aborted=false;for(var x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(aborted===false){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER)return true;if(filter===type)return true;var name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function generateId(ty){if(ty.parent&&ty.parent.name){return itemTypes[ty.ty]+ty.path+ty.parent.name+ty.name}return itemTypes[ty.ty]+ty.path+ty.name}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,}}function handleAliases(ret,query,filterCrates){var aliases=[];var crateAliases=[];var i;if(filterCrates!==undefined){if(ALIASES[filterCrates]&&ALIASES[filterCrates][query.search]){for(i=0;iMAX_RESULTS){ret.others.pop()}};onEach(aliases,pushFunc);onEach(crateAliases,pushFunc)}var nSearchWords=searchWords.length;var i;var ty;var fullId;var returned;var in_args;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim()};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0;i1?paths.length-1:1);var lev;for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue}else if(lev>0){lev_add=lev/10}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=generateId(ty);if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||searchWords[j].replace(/_/g,"").indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=searchWords[j].replace(/_/g,"").indexOf(val)}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){lev=MAX_LEV_DISTANCE+1}else{lev+=1}}in_args=findArg(ty,valGenerics,false,typeFilter);returned=checkReturned(ty,valGenerics,false,typeFilter);lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1}else{lev=0}}if(in_args<=MAX_LEV_DISTANCE){if(results_in_args[fullId]===undefined){results_in_args[fullId]={id:j,index:index,lev:in_args,}}results_in_args[fullId].lev=Math.min(results_in_args[fullId].lev,in_args)}if(returned<=MAX_LEV_DISTANCE){if(results_returned[fullId]===undefined){results_returned[fullId]={id:j,index:index,lev:returned,}}results_returned[fullId].lev=Math.min(results_returned[fullId].lev,returned)}if(index!==-1||lev<=MAX_LEV_DISTANCE){if(index!==-1&&paths.length<2){lev=0}if(results[fullId]===undefined){results[fullId]={id:j,index:index,lev:lev,}}results[fullId].lev=Math.min(results[fullId].lev,lev)}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results),};handleAliases(ret,query,filterCrates);return ret}function validateResult(name,path,keys,parent){for(var i=0;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false}}return true}function getQuery(raw){var matches,type,query;query=raw;matches=query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i);if(matches){type=matches[1].replace(/^const$/,"constant");query=query.substring(matches[0].length)}return{raw:raw,query:query,type:type,id:query+type}}function initSearchNav(){var hoverTimeout;var click_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}var dst=e.target.getElementsByTagName("a");if(dst.length<1){return}dst=dst[0];if(window.location.pathname===dst.pathname){hideSearchResults();document.location.href=dst.href}};var mouseover_func=function(e){if(mouseMovedAfterSearch){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}clearTimeout(hoverTimeout);hoverTimeout=setTimeout(function(){onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){removeClass(i_e,"highlighted")})});addClass(el,"highlighted")},20)}};onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){i_e.onclick=click_func;i_e.onmouseover=mouseover_func})});search_input.onkeydown=function(e){var actives=[[],[],[]];var current=0;onEachLazy(document.getElementById("results").childNodes,function(e){onEachLazy(e.getElementsByClassName("highlighted"),function(h_e){actives[current].push(h_e)});current+=1});if(e.which===38){if(!actives[currentTab].length||!actives[currentTab][0].previousElementSibling){return}addClass(actives[currentTab][0].previousElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted");e.preventDefault()}else if(e.which===40){if(!actives[currentTab].length){var results=document.getElementById("results").childNodes;if(results.length>0){var res=results[currentTab].getElementsByClassName("result");if(res.length>0){addClass(res[0],"highlighted")}}}else if(actives[currentTab][0].nextElementSibling){addClass(actives[currentTab][0].nextElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}e.preventDefault()}else if(e.which===13){if(actives[currentTab].length){document.location.href=actives[currentTab][0].getElementsByTagName("a")[0].href}}else if(e.which===9){if(e.shiftKey){printTab(currentTab>0?currentTab-1:2)}else{printTab(currentTab>1?0:currentTab+1)}e.preventDefault()}else if(e.which===16){}else if(actives[currentTab].length>0){removeClass(actives[currentTab][0],"highlighted")}}}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;var path=item.path;if(type==="mod"){displayPath=path+"::";href=rootPath+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="primitive"||type==="keyword"){displayPath="";href=rootPath+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=rootPath+name+"/index.html"}else if(item.parent!==undefined){var myparent=item.parent;var anchor="#"+type+"."+name;var parentType=itemTypes[myparent.ty];var pageType=parentType;var pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){var splitPath=item.path.split("::");var enumName=splitPath.pop();path=splitPath.join("::");displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=rootPath+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){var extraStyle="";if(display===false){extraStyle=" style=\"display: none;\""}var output="";var duplicates={};var length=0;if(array.length>0){output="";array.forEach(function(item){var name,type;name=item.name;type=itemTypes[item.ty];if(item.is_alias!==true){if(duplicates[item.fullPath]){return}duplicates[item.fullPath]=true}length+=1;output+=""});output+="
"+""+(item.is_alias===true?(""+item.alias+"  - see "):"")+item.displayPath+""+name+""+""+""+escape(item.desc)+" 
"}else{output="
No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(currentTab===tabNb){return"
"+text+"
("+nbElems+")
"}return"
"+text+"
("+nbElems+")
"}function showResults(results){var search=getSearchElement();if(results.others.length===1&&getSettingValue("go-to-only-result")==="true"&&(!search.firstChild||search.firstChild.innerText!==getSearchLoadingText())){var elem=document.createElement("a");elem.href=results.others[0].href;elem.style.display="none";document.body.appendChild(elem);elem.click();return}var query=getQuery(search_input.value);currentResults=query.id;var ret_others=addTab(results.others,query);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);var output="

Results for "+escape(query.query)+(query.type?" (type: "+escape(query.type)+")":"")+"

"+"
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"+ret_others[0]+ret_in_args[0]+ret_returned[0]+"
";search.innerHTML=output;showSearchResults(search);var tds=search.getElementsByTagName("td");var td_width=0;if(tds.length>0){td_width=tds[0].offsetWidth}var width=search.offsetWidth-40-td_width;onEachLazy(search.getElementsByClassName("desc"),function(e){e.style.width=width+"px"});initSearchNav();var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0)};elems[1].onclick=function(){printTab(1)};elems[2].onclick=function(){printTab(2)};printTab(currentTab)}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev}}return start}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1}}}return ret}var queries=query.raw.split(",");var results={"in_args":[],"returned":[],"others":[],};for(var i=0;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),}}return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&hasOwnProperty(rawSearchIndex,elem.value)){return elem.value}return undefined}function search(e,forced){var params=getQueryStringParams();var query=getQuery(search_input.value.trim());if(e){e.preventDefault()}if(query.query.length===0){return}if(forced!==true&&query.id===currentResults){if(query.query.length>0){putBackSearch(search_input)}return}searchTitle="Results for "+query.query+" - Rust";if(browserSupportsHistoryApi()){if(!history.state&&!params.search){history.pushState(query,"","?search="+encodeURIComponent(query.raw))}else{history.replaceState(query,"","?search="+encodeURIComponent(query.raw))}}var filterCrates=getFilterCrates();showResults(execSearch(query,index,filterCrates))}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i;var currentIndex=0;for(var crate in rawSearchIndex){if(!hasOwnProperty(rawSearchIndex,crate)){continue}var crateSize=0;searchWords.push(crate);searchIndex.push({crate:crate,ty:1,name:crate,path:"",desc:rawSearchIndex[crate].doc,type:null,});currentIndex+=1;var items=rawSearchIndex[crate].i;var paths=rawSearchIndex[crate].p;var aliases=rawSearchIndex[crate].a;var len=paths.length;for(i=0;i0){search_input.value=params.search;search(e)}else{search_input.value="";hideSearchResults()}})}search()}index=buildIndex(rawSearchIndex);startSearch();if(rootPath==="../"||rootPath==="./"){var sidebar=document.getElementsByClassName("sidebar-elems")[0];if(sidebar){var div=document.createElement("div");div.className="block crate";div.innerHTML="

Crates

";var ul=document.createElement("ul");div.appendChild(ul);var crates=[];for(var crate in rawSearchIndex){if(!hasOwnProperty(rawSearchIndex,crate)){continue}crates.push(crate)}crates.sort();for(var i=0;i"+""+"
"+code.outerHTML+"
";list.appendChild(display)}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function labelForToggleButton(sectionIsCollapsed){if(sectionIsCollapsed){return"+"}return"\u2212"}function onEveryMatchingChild(elem,className,func){if(elem&&className&&func){var length=elem.childNodes.length;var nodes=elem.childNodes;for(var i=0;i"+labelForToggleButton(sectionIsCollapsed)+"
]";return toggle}function createToggle(toggle,otherMessage,fontSize,extraClass,show){var span=document.createElement("span");span.className="toggle-label";if(show){span.style.display="none"}if(!otherMessage){span.innerHTML=" Expand description"}else{span.innerHTML=otherMessage}if(fontSize){span.style.fontSize=fontSize}var mainToggle=toggle.cloneNode(true);mainToggle.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper";if(!show){addClass(wrapper,"collapsed");var inner=mainToggle.getElementsByClassName("inner");if(inner&&inner.length>0){inner[0].innerHTML="+"}}if(extraClass){addClass(wrapper,extraClass)}wrapper.appendChild(mainToggle);return wrapper}(function(){var toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}var toggle=createSimpleToggle(false);var hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";var hideImplementors=getSettingValue("auto-collapse-implementors")!=="false";var pageId=getPageId();var func=function(e){var next=e.nextElementSibling;if(!next){return}if(hasClass(next,"docblock")===true||(hasClass(next,"stability")===true&&hasClass(next.nextElementSibling,"docblock")===true)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideMethodDocs===true&&hasClass(e,"method")===true){collapseDocs(newToggle,"hide",pageId)}}};var funcImpl=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"docblock")){next=next.nextElementSibling}if(!next){return}if(hasClass(e,"impl")&&(next.getElementsByClassName("method").length>0||next.getElementsByClassName("associatedconstant").length>0)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideImplementors===true&&e.parentNode.id==="implementors-list"){collapseDocs(newToggle,"hide",pageId)}}};onEachLazy(document.getElementsByClassName("method"),func);onEachLazy(document.getElementsByClassName("associatedconstant"),func);onEachLazy(document.getElementsByClassName("impl"),funcImpl);var impl_call=function(){};if(hideMethodDocs===true){impl_call=function(e,newToggle){if(e.id.match(/^impl(?:-\d+)?$/)===null){if(hasClass(e,"impl")===true){collapseDocs(newToggle,"hide",pageId)}}}}var newToggle=document.createElement("a");newToggle.href="javascript:void(0)";newToggle.className="collapse-toggle hidden-default collapsed";newToggle.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";function toggleClicked(){if(hasClass(this,"collapsed")){removeClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("hidden"),function(x){if(hasClass(x,"content")===false){removeClass(x,"hidden");addClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(false)+"] Hide undocumented items"}else{addClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("x"),function(x){if(hasClass(x,"content")===false){addClass(x,"hidden");removeClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items"}}onEachLazy(document.getElementsByClassName("impl-items"),function(e){onEachLazy(e.getElementsByClassName("associatedconstant"),func);var hiddenElems=e.getElementsByClassName("hidden");var needToggle=false;var hlength=hiddenElems.length;for(var i=0;i"+getSearchLoadingText()+"";showSearchResults(search)}var sidebar_menu=document.getElementsByClassName("sidebar-menu")[0];if(sidebar_menu){sidebar_menu.onclick=function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(hasClass(sidebar,"mobile")===true){hideSidebar()}else{showSidebar()}}}if(main){onEachLazy(main.getElementsByClassName("loading-content"),function(e){e.remove()});onEachLazy(main.childNodes,function(e){if(e.tagName==="H2"||e.tagName==="H3"){var nextTagName=e.nextElementSibling.tagName;if(nextTagName=="H2"||nextTagName=="H3"){e.nextElementSibling.style.display="flex"}else{e.nextElementSibling.style.display="block"}}})}function enableSearchInput(){if(search_input){search_input.removeAttribute('disabled')}}window.addSearchOptions=function(crates){var elem=document.getElementById("crate-search");if(!elem){enableSearchInput();return}var crates_text=[];if(Object.keys(crates).length>1){for(var crate in crates){if(hasOwnProperty(crates,crate)){crates_text.push(crate)}}}crates_text.sort(function(a,b){var lower_a=a.toLowerCase();var lower_b=b.toLowerCase();if(lower_alower_b){return 1}return 0});var savedCrate=getSettingValue("saved-filter-crate");for(var i=0;ithe rustdoc book.";var container=document.createElement("div");var shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["T","Focus the theme picker menu"],["↑","Move up in search results"],["↓","Move down in search results"],["↹","Switch tab"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0]+"
"+x[1]+"
").join("");var div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";var infos=["Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + * -> vec)","Search multiple things at once by splitting your query with comma (e.g., \ + str,u8 or String,struct:Vec,test)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;container.appendChild(book_info);container.appendChild(div_shortcuts);container.appendChild(div_infos);popup.appendChild(container);insertAfter(popup,getSearchElement());buildHelperPopup=function(){}}onHashChange(null);window.onhashchange=onHashChange}());window.onunload=function(){} \ No newline at end of file diff --git a/normalize.css b/normalize.css new file mode 100644 index 000000000..6d692b50c --- /dev/null +++ b/normalize.css @@ -0,0 +1,2 @@ + /*! normalize.css v3.0.0 | MIT License | git.io/normalize */ +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} \ No newline at end of file diff --git a/noscript.css b/noscript.css new file mode 100644 index 000000000..351b41cf8 --- /dev/null +++ b/noscript.css @@ -0,0 +1 @@ +#main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;}#main>h2+div,#main>h3+div{display:block;}#main>h2+h3{display:flex;} \ No newline at end of file diff --git a/opencl-interop/Cargo.toml b/opencl-interop/Cargo.toml deleted file mode 100644 index 6ee2a97d5..000000000 --- a/opencl-interop/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "af-opencl-interop" -version = "3.7.1" -description = "ArrayFire is a high performance software library for parallel computing with an easy-to-use API. This crate is an addition on top of ArrayFire crate to enable users to mix RAW CUDA code in rust and ArrayFire." -authors = ["Pradeep Garigipati "] -documentation = "http://arrayfire.github.io/arrayfire-rust/af_opencl_interop/index.html" -homepage = "https://github.com/arrayfire/arrayfire-rust" -repository = "https://github.com/arrayfire/arrayfire-rust/tree/master/opencl-interop" -license = "BSD-3-Clause" -edition = "2018" - -[dependencies] -libc = "0.2" -arrayfire = { path = "../" } -cl-sys = "0.4.2" - -[dev-dependencies] -ocl-core = "0.11.2" - -[[example]] -name = "afocl_custom_kernel" -path = "examples/custom_kernel.rs" - -[[example]] -name = "ocl_af_app" -path = "examples/ocl_af_app.rs" diff --git a/opencl-interop/README.md b/opencl-interop/README.md deleted file mode 100644 index 9b6bda327..000000000 --- a/opencl-interop/README.md +++ /dev/null @@ -1,55 +0,0 @@ -[![ci][19]][16] [![][18]][3] [![][17]][4] - -> This crate has known issue: Unified API library of ArrayFire used by Rust bindings has bug - that doesn't let us use functions necessary for this crate to work as expected. The associated - fix has already been submitted and should be in next release of ArrayFire i.e. either v3.7.3 or - v.3.8. - -# ArrayFire OpenCL Interop - -This crate is an addition on top of [ArrayFire][1] crate to enable users to mix RAW OpenCL code in rust -and [ArrayFire][1]. - -## Supported platforms - -Supported on all platforms [arrayfire-rust][1] is supported. - -## Usage - -Command to build the crate -``` -cargo build -p af-opencl-interop -``` - -Use the following command to run an example -``` -cargo run -p af-opencl-interop --example afocl_custom_kernel -``` - -This crate can be used by directly using the packages on crates.io or building them on your own. -The process for this can be found on [arrayfire-rust#readme][2] - -## Acknowledgements - -The ArrayFire library is written by developers at [ArrayFire][14] LLC with [contributions][15] -from several individuals. The developers at ArrayFire LLC have received partial financial support -from several grants and institutions. Those that wish to receive public acknowledgement are listed -below: - -### Grants - -This material is based upon work supported by the DARPA SBIR Program Office under Contract Numbers -W31P4Q-14-C-0012 and W31P4Q-15-C-0008. Any opinions, findings and conclusions or recommendations -expressed in this material are those of the author(s) and do not necessarily reflect the views of -the DARPA SBIR Program Office. - -[1]: https://github.com/arrayfire/arrayfire-rust -[2]: https://github.com/arrayfire/arrayfire-rust/blob/master/README.md -[3]: http://arrayfire.github.io/arrayfire-rust/af_opencl_interop/index.html -[4]: https://join.slack.com/t/arrayfire-org/shared_invite/MjI4MjIzMDMzMTczLTE1MDI5ODg4NzYtN2QwNGE3ODA5OQ -[14]: https://arrayfire.com/ -[15]: https://github.com/arrayfire/arrayfire_rust/graphs/contributors -[16]: https://github.com/arrayfire/arrayfire-rust/actions?workflow=CI -[17]: https://img.shields.io/badge/af_opencl_interop-community-e69138?logo=slack -[18]: https://img.shields.io/badge/af_opencl_interop-Docs-blue?logo=readthedocs -[19]: https://github.com/arrayfire/arrayfire-rust/workflows/ci/badge.svg?event=push diff --git a/opencl-interop/examples/custom_kernel.rs b/opencl-interop/examples/custom_kernel.rs deleted file mode 100644 index 7780a9d94..000000000 --- a/opencl-interop/examples/custom_kernel.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! A trivial example. Copied from ocl-core crate repository. -use af_opencl_interop as afcl; -use arrayfire as af; - -use ocl_core::{ArgVal, Event}; - -use std::ffi::CString; - -fn main() { - // Set the arrayfire backend to use OpenCL first, - // because CUDA is the automatically preferred if available - af::set_backend(af::Backend::OPENCL); - - af::info(); - let dims = af::dim4!(8); - let af_buffer = af::constant(0f32, dims.clone()); - af::af_print!("af_buffer", af_buffer); - - let src = r#" - __kernel void add(__global float* buffer, float scalar) { - buffer[get_global_id(0)] += scalar; - } - "#; - - let af_did = afcl::get_device_id(); - let af_ctx = afcl::get_context(false); - let af_que = afcl::get_queue(false); - - let _devid = unsafe { ocl_core::DeviceId::from_raw(af_did) }; - let contx = unsafe { ocl_core::Context::from_raw_copied_ptr(af_ctx) }; - let queue = unsafe { ocl_core::CommandQueue::from_raw_copied_ptr(af_que) }; - - // Define which platform and device(s) to use. Create a context, - // queue, and program then define some dims.. - let src_cstring = CString::new(src).unwrap(); - let program = ocl_core::create_program_with_source(&contx, &[src_cstring]).unwrap(); - ocl_core::build_program( - &program, - None::<&[()]>, - &CString::new("").unwrap(), - None, - None, - ) - .unwrap(); - - // Fetch cl_mem from ArrayFire Array - let ptr = unsafe { af_buffer.device_ptr() }; - let buffer = unsafe { ocl_core::Mem::from_raw_copied_ptr(ptr) }; - - // Create a kernel with arguments matching those in the source above: - let kernel = ocl_core::create_kernel(&program, "add").unwrap(); - ocl_core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap(); - ocl_core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap(); - - let ocl_dims: [usize; 3] = [dims[0] as usize, dims[1] as usize, dims[2] as usize]; - unsafe { - ocl_core::enqueue_kernel( - &queue, - &kernel, - 1, - None, - &ocl_dims, - None, - None::, - None::<&mut Event>, - ) - .unwrap(); - } - ocl_core::finish(&queue).unwrap(); - af_buffer.unlock(); //Give back control of cl_mem to ArrayFire memory manager - - af::af_print!("af_buffer after running Custom Kernel on it", af_buffer); -} diff --git a/opencl-interop/examples/ocl_af_app.rs b/opencl-interop/examples/ocl_af_app.rs deleted file mode 100644 index 24fd09ead..000000000 --- a/opencl-interop/examples/ocl_af_app.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! A trivial example. Copied from ocl-core crate repository. -use af_opencl_interop as afcl; -use arrayfire as af; - -use ocl_core::{retain_mem_object, ContextProperties, Event}; - -fn main() { - // Set the arrayfire backend to use OpenCL first, - // because CUDA is the automatically preferred if available - af::set_backend(af::Backend::OPENCL); - - // Choose platform & device(s) to use. Create a context, queue, - let platform_id = ocl_core::default_platform().unwrap(); - let device_ids = ocl_core::get_device_ids(&platform_id, None, None).unwrap(); - let device_id = device_ids[0]; - let context_properties = ContextProperties::new().platform(platform_id); - let context = - ocl_core::create_context(Some(&context_properties), &[device_id], None, None).unwrap(); - let queue = ocl_core::create_command_queue(&context, &device_id, None).unwrap(); - let dims = [8, 1, 1]; - - // Create a `Buffer`: - let mut vec = vec![1.0f32; dims[0]]; - let buffer = unsafe { - ocl_core::create_buffer( - &context, - ocl_core::MEM_READ_WRITE | ocl_core::MEM_COPY_HOST_PTR, - dims[0], - Some(&vec), - ) - .unwrap() - }; - ocl_core::finish(&queue).unwrap(); //sync up before switching to arrayfire - - // Add custom device, context and associated queue to ArrayFire - unsafe { - afcl::add_device_context(device_id.as_raw(), context.as_ptr(), queue.as_ptr()); - afcl::set_device_context(device_id.as_raw(), context.as_ptr()); - } - af::info(); - - unsafe { - retain_mem_object(&buffer).unwrap(); - } - let mut af_buffer = af::Array::new_from_device_ptr( - buffer.as_ptr() as *mut f32, - af::Dim4::new(&[dims[0] as u64, 1, 1, 1]), - ); - - af::af_print!("GPU Buffer before modification:", af_buffer); - - af_buffer = af_buffer + 10f32; - - af::sync(af::get_device()); - unsafe { - let ptr = af_buffer.device_ptr(); - let obuf = ocl_core::Mem::from_raw_copied_ptr(ptr); - - // Read results from the device into a vector: - ocl_core::enqueue_read_buffer( - &queue, - &obuf, - true, - 0, - &mut vec, - None::, - None::<&mut Event>, - ) - .unwrap(); - } - println!("GPU buffer on host after ArrayFire operation: {:?}", vec); - - // Remove device from ArrayFire management towards Application Exit - af::set_device(0); // Cannot pop when in Use, hence switch to another device - unsafe { - afcl::delete_device_context(device_id.as_raw(), context.as_ptr()); - } -} diff --git a/opencl-interop/examples/trivial.rs b/opencl-interop/examples/trivial.rs deleted file mode 100644 index d29020efb..000000000 --- a/opencl-interop/examples/trivial.rs +++ /dev/null @@ -1,85 +0,0 @@ -//! A trivial example. -//! -//! Copied from ocl. - -extern crate ocl_core as core; - -use crate::core::{ArgVal, ContextProperties, Event}; -use std::ffi::CString; - -#[allow(dead_code, unused_variables, unused_mut)] -fn main() { - let src = r#" - __kernel void add(__global float* buffer, float scalar) { - buffer[get_global_id(0)] += scalar; - } - "#; - - // (1) Define which platform and device(s) to use. Create a context, - // queue, and program then define some dims.. - let platform_id = core::default_platform().unwrap(); - let device_ids = core::get_device_ids(&platform_id, None, None).unwrap(); - let device_id = device_ids[0]; - let context_properties = ContextProperties::new().platform(platform_id); - let context = - core::create_context(Some(&context_properties), &[device_id], None, None).unwrap(); - let src_cstring = CString::new(src).unwrap(); - let program = core::create_program_with_source(&context, &[src_cstring]).unwrap(); - core::build_program( - &program, - None::<&[()]>, - &CString::new("").unwrap(), - None, - None, - ) - .unwrap(); - let queue = core::create_command_queue(&context, &device_id, None).unwrap(); - let dims = [1 << 20, 1, 1]; - - // (2) Create a `Buffer`: - let mut vec = vec![0.0f32; dims[0]]; - let buffer = unsafe { - core::create_buffer( - &context, - core::MEM_READ_WRITE | core::MEM_COPY_HOST_PTR, - dims[0], - Some(&vec), - ) - .unwrap() - }; - - // (3) Create a kernel with arguments matching those in the source above: - let kernel = core::create_kernel(&program, "add").unwrap(); - core::set_kernel_arg(&kernel, 0, ArgVal::mem(&buffer)).unwrap(); - core::set_kernel_arg(&kernel, 1, ArgVal::scalar(&10.0f32)).unwrap(); - - unsafe { - // (4) Run the kernel: - core::enqueue_kernel( - &queue, - &kernel, - 1, - None, - &dims, - None, - None::, - None::<&mut Event>, - ) - .unwrap(); - - // (5) Read results from the device into a vector: - core::enqueue_read_buffer( - &queue, - &buffer, - true, - 0, - &mut vec, - None::, - None::<&mut Event>, - ) - .unwrap(); - } - - // Print an element: - println!("The value at index [{}] is now '{}'!", 200007, vec[200007]); -} diff --git a/opencl-interop/src/lib.rs b/opencl-interop/src/lib.rs deleted file mode 100644 index 068e9ec9a..000000000 --- a/opencl-interop/src/lib.rs +++ /dev/null @@ -1,153 +0,0 @@ -//! af-opencl-interop package is to used only when the application intends to mix -//! arrayfire code with raw OpenCL code. -//! -//! Functions from this crate return OpenCL C API opaque pointers typedefs -//! -//! - [cl_device_id](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_device_id.html) -//! - [cl_context](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_context.html) -//! - [cl_command_queue](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_command_queue.html) - -use arrayfire::{handle_error_general, AfError}; -use cl_sys::{ - cl_command_queue, cl_context, cl_device_id, CL_DEVICE_TYPE_ACCELERATOR, CL_DEVICE_TYPE_ALL, - CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_DEFAULT, CL_DEVICE_TYPE_GPU, -}; -use libc::c_int; -use std::mem; - -/// OpenCL Vendor Platform -#[repr(i32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum VendorPlatform { - AMD = 0, - APPLE = 1, - INTEL = 2, - NVIDIA = 3, - BEIGNET = 4, - POCL = 5, - UNKNOWN = -1, -} - -/// OpenCL Device Type -#[repr(u64)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum DeviceType { - DEFAULT = CL_DEVICE_TYPE_DEFAULT, - CPU = CL_DEVICE_TYPE_CPU, - GPU = CL_DEVICE_TYPE_GPU, - ACCEL = CL_DEVICE_TYPE_ACCELERATOR, - ALL = CL_DEVICE_TYPE_ALL, -} - -extern "C" { - fn afcl_get_context(ctx: *mut cl_context, retain: bool) -> c_int; - fn afcl_get_queue(queue: *mut cl_command_queue, retain: bool) -> c_int; - fn afcl_get_device_id(out: *mut cl_device_id) -> c_int; - fn afcl_set_device_id(id: cl_device_id) -> c_int; - - fn afcl_add_device_context( - dev_id: cl_device_id, - ctx: cl_context, - queue: cl_command_queue, - ) -> c_int; - fn afcl_set_device_context(dev_id: cl_device_id, ctx: cl_context) -> c_int; - fn afcl_delete_device_context(dev_id: cl_device_id, ctx: cl_context) -> c_int; - - fn afcl_get_device_type(dtype: *mut c_int) -> c_int; - fn afcl_get_platform(ptype: *mut c_int) -> c_int; -} - -/// Get the handle to active ArrayFire OpenCL context -pub fn get_context(retain: bool) -> cl_context { - unsafe { - let mut out: cl_context = std::ptr::null_mut(); - let err_val = afcl_get_context(&mut out as *mut cl_context, retain); - handle_error_general(AfError::from(err_val)); - out - } -} - -/// Get the handle to active ArrayFire OpenCL command queue -pub fn get_queue(retain: bool) -> cl_command_queue { - unsafe { - let mut out: cl_command_queue = std::ptr::null_mut(); - let err_val = afcl_get_queue(&mut out as *mut cl_command_queue, retain); - handle_error_general(AfError::from(err_val)); - out - } -} - -/// Get the handle to active ArrayFire OpenCL device -pub fn get_device_id() -> cl_device_id { - unsafe { - let mut out: cl_device_id = std::ptr::null_mut(); - let err_val = afcl_get_device_id(&mut out as *mut cl_device_id); - handle_error_general(AfError::from(err_val)); - out - } -} - -/// Set the cl_device_id as the active ArrayFire OpenCL device -/// -/// # Safety -/// -/// This function is to be only called if user intends to set a particular -/// opencl device explicitly. This is low level function and it's for only -/// advanced users. -pub unsafe fn set_device_id(dev_id: cl_device_id) { - let err_val = afcl_set_device_id(dev_id); - handle_error_general(AfError::from(err_val)); -} - -/// Push user provided device, context and queue tuple to ArrayFire device mamanger -/// -/// # Safety -/// -/// This function is to be only called if user intends to add a opencl device context -/// explicitly. This is low level function and it's for only advanced users. -pub unsafe fn add_device_context(dev_id: cl_device_id, ctx: cl_context, queue: cl_command_queue) { - let err_val = afcl_add_device_context(dev_id, ctx, queue); - handle_error_general(AfError::from(err_val)); -} - -/// Set the device identified by device & context pair as the active device for ArrayFire -/// -/// # Safety -/// -/// This function is to be only called if user intends mark a given opencl device -/// as current device. It is for advanced users only. -pub unsafe fn set_device_context(dev_id: cl_device_id, ctx: cl_context) { - let err_val = afcl_set_device_context(dev_id, ctx); - handle_error_general(AfError::from(err_val)); -} - -/// Remove the user provided device, context pair from ArrayFire device mamanger -/// -/// # Safety -/// -/// This function is to be only called if user intends to delete a prior added -/// opencl device context. Using this for devices not added by user explicitly -/// can result in undefined behavior. -pub unsafe fn delete_device_context(dev_id: cl_device_id, ctx: cl_context) { - let err_val = afcl_delete_device_context(dev_id, ctx); - handle_error_general(AfError::from(err_val)); -} - -///// Fetch Active ArrayFire device's type i.e. CPU/GPU/Accelerator etc. -pub fn get_device_type() -> DeviceType { - let mut out: i32 = 0; - let err_val = unsafe { afcl_get_device_type(&mut out as *mut c_int) }; - handle_error_general(AfError::from(err_val)); - match out { - -1 => unsafe { mem::transmute(out as u64) }, - _ => DeviceType::ALL, - } -} - -/// Fetch Active ArrayFire device's vendor platform -pub fn get_platform() -> VendorPlatform { - let mut out: i32 = 0; - let err_val = unsafe { afcl_get_platform(&mut out as *mut c_int) }; - handle_error_general(AfError::from(err_val)); - unsafe { mem::transmute(out) } -} diff --git a/rust-logo.png b/rust-logo.png new file mode 100644 index 000000000..74b4bd695 Binary files /dev/null and b/rust-logo.png differ diff --git a/rustdoc.css b/rustdoc.css new file mode 100644 index 000000000..f9242a832 --- /dev/null +++ b/rustdoc.css @@ -0,0 +1 @@ + @font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular.woff") format('woff');}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url("SourceSerifPro-Regular.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:italic;font-weight:400;src:local('Source Serif Pro Italic'),url("SourceSerifPro-It.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro Bold'),url("SourceSerifPro-Bold.ttf.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold.woff") format('woff');}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:16px/1.4 "Source Serif Pro",serif;margin:0;position:relative;padding:10px 15px 20px 15px;-webkit-font-feature-settings:"kern","liga";-moz-font-feature-settings:"kern","liga";font-feature-settings:"kern","liga";}h1{font-size:1.5em;}h2{font-size:1.4em;}h3{font-size:1.3em;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.notable),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){font-weight:500;margin:20px 0 15px 0;padding-bottom:6px;}h1.fqn{border-bottom:1px dashed;margin-top:0;}h1.fqn>.in-band>a:hover{text-decoration:underline;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant){border-bottom:1px solid;}h3.impl,h3.method,h4.method,h3.type,h4.type,h4.associatedconstant{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}h3.impl,h3.method,h3.type{padding-left:15px;}h1,h2,h3,h4,.sidebar,a.source,.search-input,.content table td:first-child>a,.collapse-toggle,div.item-list .out-of-band,#source-sidebar,#sidebar-toggle{font-family:"Fira Sans",sans-serif;}.content ul.crate a.crate{font:16px/1.6 "Fira Sans";}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}code,pre,a.test-arrow{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code,.docblock code.spotlight{padding:0;}.docblock code.spotlight :last-child{padding-bottom:0.6em;}pre{padding:14px;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.source .content{margin-top:50px;max-width:none;overflow:visible;margin-left:0px;min-width:70em;}nav.sub{font-size:16px;text-transform:uppercase;}.sidebar{width:200px;position:fixed;left:0;top:0;bottom:0;overflow:auto;}*{scrollbar-width:initial;}.sidebar{scrollbar-width:thin;}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;}.sidebar .block>ul>li{margin-right:-10px;}.content,nav{max-width:960px;}.hidden{display:none !important;}.logo-container{height:100px;width:100px;position:relative;margin:20px auto;display:block;margin-top:10px;}.logo-container>img{max-width:100px;max-height:100px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;}.sidebar .location{border:1px solid;font-size:17px;margin:30px 10px 20px 10px;text-align:center;word-wrap:break-word;}.sidebar .version{font-size:15px;text-align:center;border-bottom:1px solid;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;}.location:empty{border:none;}.location a:first-child{font-weight:500;}.block{padding:0;margin-bottom:14px;}.block h2,.block h3{margin-top:0;margin-bottom:8px;text-align:center;}.block ul,.block li{margin:0 10px;padding:0;list-style:none;}.block a{display:block;text-overflow:ellipsis;overflow:hidden;line-height:15px;padding:7px 5px;font-size:14px;font-weight:300;transition:border 500ms ease-out;}.sidebar-title{border-top:1px solid;border-bottom:1px solid;text-align:center;font-size:17px;margin-bottom:5px;}.sidebar-links{margin-bottom:15px;}.sidebar-links>a{padding-left:10px;width:100%;}.sidebar-menu{display:none;}.content{padding:15px 0;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc:not(.source) .example-wrap{display:inline-flex;margin-bottom:10px;position:relative;}.example-wrap{width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;padding:13px 8px;text-align:right;}.rustdoc:not(.source) .example-wrap>pre.rust{width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre{margin:0;}#search{margin-left:230px;position:relative;}#results{position:absolute;right:0;left:0;overflow:auto;}#results>table{width:100%;table-layout:fixed;margin-bottom:40px;}.content pre.line-numbers{float:left;border:none;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.line-numbers span{cursor:pointer;}.docblock-short{overflow-wrap:anywhere;}.docblock-short p{display:inline;}.docblock-short p{overflow:hidden;text-overflow:ellipsis;margin:0;}.docblock code,.docblock-short code{white-space:pre-wrap;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom:1px solid;}#main>.docblock h1{font-size:1.3em;}#main>.docblock h2{font-size:1.15em;}#main>.docblock h3,#main>.docblock h4,#main>.docblock h5{font-size:1em;}#main>h2+div,#main>h2+h3,#main>h3+div{display:none;flex-wrap:wrap;}.docblock h1{font-size:1em;}.docblock h2{font-size:0.95em;}.docblock h3,.docblock h4,.docblock h5{font-size:0.9em;}.docblock{margin-left:24px;position:relative;}.content .out-of-band{float:right;font-size:23px;margin:0px;padding:0px;font-weight:normal;}h3.impl>.out-of-band{font-size:21px;}h4.method>.out-of-band{font-size:19px;}h4>code,h3>code,.invisible>code{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{margin:0px;padding:0px;}.in-band>code{display:inline-block;}#main{position:relative;}#main>.since{top:inherit;font-family:"Fira Sans",sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.content td{vertical-align:top;}.content td:first-child{padding-right:20px;}.content td p:first-child{margin-top:0;}.content td h1,.content td h2{margin-left:0;font-size:1.1em;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);border:1px dashed;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.content .multi-column{-moz-column-count:5;-moz-column-gap:2.5em;-webkit-column-count:5;-webkit-column-gap:2.5em;column-count:5;column-gap:2.5em;}.content .multi-column li{width:100%;display:inline-block;}.content .method{font-size:1em;position:relative;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8em;}.content .methods>div:not(.notable-traits){margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items>h4{border-bottom:0;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.toggle-wrapper.marg-left>.collapse-toggle{left:-24px;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .stability code{font-size:90%;}.content .stability{position:relative;margin-left:33px;margin-top:-13px;}.sub-variant>div>.stability{margin-top:initial;}.content .stability::before{content:'⬑';font-size:25px;position:absolute;top:-6px;left:-19px;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{margin-left:20px;}.content .impl-items .docblock,.content .impl-items .stability{margin-bottom:.6em;}.content .impl-items>.stability{margin-left:40px;}.methods>.stability,.content .impl-items>.stability{margin-top:-8px;}.impl-items{flex-basis:100%;}#main>.stability{margin-top:0;}nav:not(.sidebar){border-bottom:1px solid;padding-bottom:10px;margin-bottom:10px;}nav.main{padding:20px 0;text-align:center;}nav.main .current{border-top:1px solid;border-bottom:1px solid;}nav.main .separator{border:1px solid;display:inline-block;height:23px;margin:0 20px;}nav.sum{text-align:right;}nav.sub form{display:inline;}nav.sub,.content{margin-left:230px;}a{text-decoration:none;background:transparent;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor,.impl:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-7px;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-28px;padding-right:10px;}.anchor:before{content:'\2002\00a7\2002';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.stability a{text-decoration:underline;}.invisible>.srclink,h4>code+.srclink{position:absolute;top:0;right:0;font-size:17px;font-weight:normal;}.block a.current.crate{font-weight:500;}.search-container{position:relative;}.search-container>div{display:inline-flex;width:calc(100% - 63px);}#crate-search{margin-top:5px;padding:6px;padding-right:19px;flex:none;border:0;border-right:0;border-radius:4px 0 0 4px;outline:none;cursor:pointer;border-right:1px solid;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;}.search-container>.top-button{position:absolute;right:0;top:10px;}.search-input{-moz-box-sizing:border-box !important;box-sizing:border-box !important;outline:none;border:none;border-radius:1px;margin-top:5px;padding:10px 16px;font-size:17px;transition:border-color 300ms ease;transition:border-radius 300ms ease-in-out;transition:box-shadow 300ms ease-in-out;width:100%;}#crate-search+.search-input{border-radius:0 1px 1px 0;width:calc(100% - 32px);}.search-input:focus{border-radius:2px;border:0;outline:0;}.search-results .desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;display:block;}.search-results a{display:block;}.content .search-results td:first-child{padding-right:0;width:50%;}.content .search-results td:first-child a{padding-right:10px;}.content .search-results td:first-child a:after{clear:both;content:"";display:block;}.content .search-results td:first-child a span{float:left;}tr.result span.primitive::after{content:' (primitive type)';font-style:italic;}tr.result span.keyword::after{content:' (keyword)';font-style:italic;}body.blur>:not(#help){filter:blur(8px);-webkit-filter:blur(8px);opacity:.7;}#help{width:100%;height:100vh;position:fixed;top:0;left:0;display:flex;justify-content:center;align-items:center;}#help>div{flex:0 0 auto;box-shadow:0 0 6px rgba(0,0,0,.2);width:550px;height:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;}#help>div>span{text-align:center;display:block;margin:10px 0;font-size:18px;border-bottom:1px solid #ccc;padding-bottom:4px;margin-bottom:6px;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:0 20px 20px 17px;;}.stab{display:table;border-width:1px;border-style:solid;padding:3px;margin-bottom:5px;font-size:90%;}.stab p{display:inline;}.stab summary{display:list-item;}.stab .emoji{font-size:1.5em;}.module-item .stab{border-radius:3px;display:inline-block;font-size:80%;line-height:1.2;margin-bottom:0;margin-right:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;position:absolute;right:0;top:0;}.impl-items .since,.impl .since{flex-grow:0;padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink{flex-grow:0;font-size:17px;font-weight:normal;}.impl-items code,.impl code{flex-grow:1;}.impl-items h4,h4.impl,h3.impl{display:flex;flex-basis:100%;font-size:16px;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:130%;top:5px;right:5px;z-index:1;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;content:'\2002\00a7\2002';}.section-header:hover a{text-decoration:none;}.section-header a{color:inherit;}.collapse-toggle{font-weight:300;position:absolute;left:-23px;top:0;}h3>.collapse-toggle,h4>.collapse-toggle{font-size:0.8em;top:5px;}.toggle-wrapper>.collapse-toggle{left:-24px;margin-top:0px;}.toggle-wrapper{position:relative;margin-top:0;}.toggle-wrapper.collapsed{height:25px;transition:height .2s;margin-bottom:.6em;}.collapse-toggle>.inner{display:inline-block;width:1.2ch;text-align:center;}.collapse-toggle.hidden-default{position:relative;margin-left:20px;}.since+.srclink{display:table-cell;padding-left:10px;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:20px;margin-right:5px;}.toggle-wrapper>.collapse-toggle{left:0;}.variant+.toggle-wrapper+.docblock>p{margin-top:5px;}.sub-variant,.sub-variant>h3{margin-top:1px !important;}#main>.sub-variant>h3{font-size:15px;margin-left:25px;margin-bottom:5px;}.sub-variant>div{margin-left:20px;margin-bottom:10px;}.sub-variant>div>span{display:block;position:relative;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.enum>.toggle-wrapper+.docblock,.struct>.toggle-wrapper+.docblock{margin-left:30px;margin-bottom:20px;margin-top:5px;}.docblock>.section-header:first-child{margin-left:15px;margin-top:0;}.docblock>.section-header:first-child:hover>a:before{left:-10px;}.enum>.collapsed,.struct>.collapsed{margin-bottom:25px;}#main>.variant,#main>.structfield{display:block;}.attributes{display:block;margin-top:0px !important;margin-right:0px;margin-bottom:0px !important;margin-left:30px;}.toggle-attributes.collapsed{margin-bottom:0;}.impl-items>.toggle-attributes{margin-left:20px;}.impl-items .attributes{font-weight:500;}:target>code{opacity:1;}.information{position:absolute;left:-25px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip .tooltiptext{width:120px;display:none;text-align:center;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;top:-5px;left:105%;z-index:10;font-size:16px;}.tooltip .tooltiptext::after{content:" ";position:absolute;top:50%;left:16px;margin-top:-5px;border-width:5px;border-style:solid;}.tooltip:hover .tooltiptext{display:inline;}.tooltip.compile_fail,.tooltip.should_panic,.tooltip.ignore{font-weight:bold;font-size:20px;}.notable-traits-tooltip{display:inline-block;cursor:pointer;}.notable-traits:hover .notable-traits-tooltiptext,.notable-traits .notable-traits-tooltiptext.force-tooltip{display:inline-block;}.notable-traits .notable-traits-tooltiptext{display:none;padding:5px 3px 3px 3px;border-radius:6px;margin-left:5px;z-index:10;font-size:16px;cursor:default;position:absolute;border:1px solid;}.notable-traits-tooltip::after{content:"\00a0\00a0\00a0";}.notable-traits .notable,.notable-traits .docblock{margin:0;}.notable-traits .docblock code.content{margin:0;padding:0;font-size:20px;}pre.rust.rust-example-rendered{position:relative;}pre.rust{tab-size:4;-moz-tab-size:4;}.search-failed{text-align:center;margin-top:20px;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>div{float:left;width:33.3%;text-align:center;font-size:18px;cursor:pointer;border-top:2px solid;}#titles>div:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>div>div.count{display:inline-block;font-size:16px;}.notable-traits{cursor:pointer;z-index:2;margin-left:5px;}h4>.notable-traits{position:absolute;left:-44px;top:2px;}#all-types{text-align:center;border:1px solid;margin:0 10px;margin-bottom:10px;display:block;border-radius:7px;}#all-types>p{margin:5px 0;}#sidebar-toggle{position:fixed;top:30px;left:300px;z-index:10;padding:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;transition:left .5s;font-size:1.2em;border:1px solid;border-left:0;}#source-sidebar{position:fixed;top:0;bottom:0;left:0;width:300px;z-index:1;overflow:auto;transition:left .5s;border-right:1px solid;}#source-sidebar>.title{font-size:1.5em;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:211px;top:19px;}.theme-picker button{outline:none;}#settings-menu,.help-button{position:absolute;top:10px;}#settings-menu{right:0;outline:none;}.help-button{right:30px;font-family:"Fira Sans",sans-serif;text-align:center;font-size:17px;}#theme-picker,#settings-menu,.help-button{padding:4px;width:27px;height:29px;border:1px solid;border-radius:3px;cursor:pointer;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px 8px;text-align:center;background:rgba(0,0,0,0);}#theme-choices>button:not(:first-child){border-top:1px solid;}@media (min-width:701px){.information:first-child>.tooltip{margin-top:16px;}}@media (max-width:700px){body{padding-top:0px;}.rustdoc>.sidebar{height:45px;min-height:40px;margin:0;margin-left:-15px;padding:0 15px;position:static;z-index:11;}.sidebar>.location{float:right;margin:0px;margin-top:2px;padding:3px 10px 1px 10px;min-height:39px;background:inherit;text-align:left;font-size:24px;}.sidebar .location:empty{padding:0;}.sidebar .logo-container{width:35px;height:35px;margin-top:5px;margin-bottom:5px;float:left;margin-left:50px;}.sidebar .logo-container>img{max-width:35px;max-height:35px;}.sidebar-menu{position:fixed;z-index:10;font-size:2rem;cursor:pointer;width:45px;left:0;text-align:center;display:block;border-bottom:1px solid;border-right:1px solid;height:45px;}.rustdoc.source>.sidebar>.sidebar-menu{display:none;}.sidebar-elems{position:fixed;z-index:1;left:0;top:45px;bottom:0;overflow-y:auto;border-right:1px solid;display:none;}.sidebar>.block.version{border-bottom:none;margin-top:12px;}nav.sub{width:calc(100% - 32px);float:right;}.content{margin-left:0px;}#main{margin-top:45px;padding:0;}.content .in-band{width:100%;}.content h4>.out-of-band{position:inherit;}.toggle-wrapper>.collapse-toggle{left:0px;}.toggle-wrapper{height:1.5em;}#search{margin-left:0;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{display:flex;}.anchor{display:none !important;}h1.fqn{overflow:initial;}.theme-picker{left:10px;top:54px;z-index:1;}h4>.notable-traits{position:absolute;left:-22px;top:24px;}#titles>div>div.count{float:left;width:100%;}#titles{height:50px;}.sidebar.mobile{position:fixed;width:100%;margin-left:0;background-color:rgba(0,0,0,0);height:100%;}.sidebar{width:calc(100% + 30px);}.show-it{display:block;width:246px;}.show-it>.block.items{margin:8px 0;}.show-it>.block.items>ul{margin:0;}.show-it>.block.items>ul>li{text-align:center;margin:2px 0;}.show-it>.block.items>ul>li>a{font-size:21px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}.collapse-toggle{left:-20px;}.impl>.collapse-toggle{left:-10px;}#all-types{margin:10px;}#sidebar-toggle{top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;}#source-sidebar{z-index:11;}#main>.line-numbers{margin-top:0;}.notable-traits .notable-traits-tooltiptext{left:0;top:100%;}.help-button{display:none;}.search-container>div{width:calc(100% - 32px);}}@media print{nav.sub,.content .out-of-band,.collapse-toggle{display:none;}}@media (max-width:416px){#titles,#titles>div{height:73px;}#main>table:not(.table-display) td{word-break:break-word;min-width:10%;}.search-container>div{display:block;width:calc(100% - 37px);}#crate-search{width:100%;border-radius:4px;border:0;}#crate-search+.search-input{width:calc(100% + 71px);margin-left:-36px;}#theme-picker,#settings-menu{padding:5px;width:31px;height:31px;}#theme-picker{margin-top:-2px;}#settings-menu{top:7px;}}h3.notable{margin:0;margin-bottom:13px;font-size:19px;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:16px;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:19px;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:17px;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main>ul{padding-left:10px;}#main>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7em;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}.type-decl>pre>.toggle-wrapper.toggle-attributes.top-attr{margin-left:0 !important;}.type-decl>pre>.docblock.attributes.top-attr{margin-left:1.8em !important;}.type-decl>pre>.toggle-attributes{margin-left:2.2em;}.type-decl>pre>.docblock.attributes{margin-left:4em;} \ No newline at end of file diff --git a/scripts/generate_documentation.sh b/scripts/generate_documentation.sh deleted file mode 100755 index c9899e332..000000000 --- a/scripts/generate_documentation.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# this script meant to be run from the root of arrayfire-rust - -cargo rustdoc -p arrayfire -- --html-in-header ./scripts/mathjax.script -cargo rustdoc -p af-cuda-interop -- --html-in-header ./scripts/mathjax.script -cargo rustdoc -p af-opencl-interop -- --html-in-header ./scripts/mathjax.script - -mdbook build tutorials-book && cp -r tutorials-book/book ./target/doc/ diff --git a/scripts/mathjax.script b/scripts/mathjax.script deleted file mode 100644 index a3050b32a..000000000 --- a/scripts/mathjax.script +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/search-index.js b/search-index.js new file mode 100644 index 000000000..cdb3e4f48 --- /dev/null +++ b/search-index.js @@ -0,0 +1,6 @@ +var searchIndex = JSON.parse('{\ +"af_cuda_interop":{"doc":"af-cuda-interop package is to used only when the…","i":[[5,"get_device_native_id","af_cuda_interop","Get active device\'s id in CUDA context",null,[[]]],[5,"set_device_native_id","","Set active device using CUDA context\'s id",null,[[]]],[5,"get_stream","","Get CUDA stream of active CUDA device",null,[[],["cudastream_t",6]]]],"p":[]},\ +"af_opencl_interop":{"doc":"af-opencl-interop package is to used only when the…","i":[[4,"VendorPlatform","af_opencl_interop","OpenCL Vendor Platform",null,null],[13,"AMD","","",0,null],[13,"APPLE","","",0,null],[13,"INTEL","","",0,null],[13,"NVIDIA","","",0,null],[13,"BEIGNET","","",0,null],[13,"POCL","","",0,null],[13,"UNKNOWN","","",0,null],[4,"DeviceType","","OpenCL Device Type",null,null],[13,"DEFAULT","","",1,null],[13,"CPU","","",1,null],[13,"GPU","","",1,null],[13,"ACCEL","","",1,null],[13,"ALL","","",1,null],[5,"get_context","","Get the handle to active ArrayFire OpenCL context",null,[[],["cl_context",6]]],[5,"get_queue","","Get the handle to active ArrayFire OpenCL command queue",null,[[],["cl_command_queue",6]]],[5,"get_device_id","","Get the handle to active ArrayFire OpenCL device",null,[[],["cl_device_id",6]]],[5,"set_device_id","","Set the cl_device_id as the active ArrayFire OpenCL device",null,[[["cl_device_id",6]]]],[5,"add_device_context","","Push user provided device, context and queue tuple to…",null,[[["cl_context",6],["cl_command_queue",6],["cl_device_id",6]]]],[5,"set_device_context","","Set the device identified by device & context pair as the…",null,[[["cl_context",6],["cl_device_id",6]]]],[5,"delete_device_context","","Remove the user provided device, context pair from…",null,[[["cl_context",6],["cl_device_id",6]]]],[5,"get_device_type","","",null,[[],["devicetype",4]]],[5,"get_platform","","Fetch Active ArrayFire device\'s vendor platform",null,[[],["vendorplatform",4]]],[11,"from","","",0,[[]]],[11,"into","","",0,[[]]],[11,"to_owned","","",0,[[]]],[11,"clone_into","","",0,[[]]],[11,"borrow","","",0,[[]]],[11,"borrow_mut","","",0,[[]]],[11,"try_from","","",0,[[],["result",4]]],[11,"try_into","","",0,[[],["result",4]]],[11,"type_id","","",0,[[],["typeid",3]]],[11,"from","","",1,[[]]],[11,"into","","",1,[[]]],[11,"to_owned","","",1,[[]]],[11,"clone_into","","",1,[[]]],[11,"borrow","","",1,[[]]],[11,"borrow_mut","","",1,[[]]],[11,"try_from","","",1,[[],["result",4]]],[11,"try_into","","",1,[[],["result",4]]],[11,"type_id","","",1,[[],["typeid",3]]],[11,"clone","","",0,[[],["vendorplatform",4]]],[11,"clone","","",1,[[],["devicetype",4]]],[11,"eq","","",0,[[["vendorplatform",4]]]],[11,"eq","","",1,[[["devicetype",4]]]],[11,"fmt","","",0,[[["formatter",3]],["result",6]]],[11,"fmt","","",1,[[["formatter",3]],["result",6]]]],"p":[[4,"VendorPlatform"],[4,"DeviceType"]]},\ +"arrayfire":{"doc":"ArrayFire is a high performance software library for…","i":[[3,"Array","arrayfire","A multidimensional data container",null,null],[3,"Dim4","","Dim4 is used to store Array dimensions",null,null],[3,"Callback","","Structure holding handle to callback function",null,null],[3,"Event","","RAII construct to manage ArrayFire events",null,null],[3,"Indexer","","Struct to manage an array of resources of type…",null,null],[3,"RandomEngine","","Random number generator engine",null,null],[3,"Seq","","Sequences are used for indexing Arrays",null,null],[3,"Window","","Used to render Array objects",null,null],[3,"Features","","A set of Array objects (usually, used in Computer vision…",null,null],[4,"AfError","","Error codes",null,null],[13,"SUCCESS","","The function returned successfully",0,null],[13,"ERR_NO_MEM","","The system or device ran out of memory",0,null],[13,"ERR_DRIVER","","There was an error in the device driver",0,null],[13,"ERR_RUNTIME","","There was an error with the runtime environment",0,null],[13,"ERR_INVALID_ARRAY","","The input array is not a valid Array object",0,null],[13,"ERR_ARG","","One of the function arguments is incorrect",0,null],[13,"ERR_SIZE","","The size is incorrect",0,null],[13,"ERR_TYPE","","The type is not suppported by this function",0,null],[13,"ERR_DIFF_TYPE","","The type of the input arrays are not compatible",0,null],[13,"ERR_BATCH","","Function does not support GFOR / batch mode",0,null],[13,"ERR_DEVICE","","Input does not belong to the current device",0,null],[13,"ERR_NOT_SUPPORTED","","The option is not supported",0,null],[13,"ERR_NOT_CONFIGURED","","This build of ArrayFire does not support this feature",0,null],[13,"ERR_NO_DBL","","This device does not support double",0,null],[13,"ERR_NO_GFX","","This build of ArrayFire was not built with graphics or…",0,null],[13,"ERR_INTERNAL","","There was an internal error either in ArrayFire or in a…",0,null],[13,"ERR_UNKNOWN","","Unknown Error",0,null],[4,"Backend","","Compute/Acceleration Backend",null,null],[13,"DEFAULT","","Default backend order: OpenCL -> CUDA -> CPU",1,null],[13,"CPU","","CPU a.k.a sequential algorithms",1,null],[13,"CUDA","","CUDA Compute Backend",1,null],[13,"OPENCL","","OpenCL Compute Backend",1,null],[4,"DType","","Types of Array data type",null,null],[13,"F32","","32 bit float",2,null],[13,"C32","","32 bit complex float",2,null],[13,"F64","","64 bit float",2,null],[13,"C64","","64 bit complex float",2,null],[13,"B8","","8 bit boolean",2,null],[13,"S32","","32 bit signed integer",2,null],[13,"U32","","32 bit unsigned integer",2,null],[13,"U8","","8 bit unsigned integer",2,null],[13,"S64","","64 bit signed integer",2,null],[13,"U64","","64 bit unsigned integer",2,null],[13,"S16","","16 bit signed integer",2,null],[13,"U16","","16 bit unsigned integer",2,null],[13,"F16","","16 bit floating point",2,null],[4,"InterpType","","Dictates the interpolation method to be used by a function",null,null],[13,"NEAREST","","Nearest Neighbor interpolation method",3,null],[13,"LINEAR","","Linear interpolation method",3,null],[13,"BILINEAR","","Bilinear interpolation method",3,null],[13,"CUBIC","","Cubic interpolation method",3,null],[13,"LOWER","","Floor indexed",3,null],[13,"LINEAR_COSINE","","Linear interpolation with cosine smoothing",3,null],[13,"BILINEAR_COSINE","","Bilinear interpolation with cosine smoothing",3,null],[13,"BICUBIC","","Bicubic interpolation",3,null],[13,"CUBIC_SPLINE","","Cubic interpolation with Catmull-Rom splines",3,null],[13,"BICUBIC_SPLINE","","Bicubic interpolation with Catmull-Rom splines",3,null],[4,"BorderType","","Helps determine how to pad kernels along borders",null,null],[13,"ZERO","","Pad using zeros",4,null],[13,"SYMMETRIC","","Pad using mirrored values along border",4,null],[13,"CLAMP_TO_EDGE","","Out of bound values are clamped to the edge",4,null],[13,"PERIODIC","","Out of bound values are mapped to range of the dimension…",4,null],[4,"Connectivity","","Used by `regions` function to identify type of connectivity",null,null],[13,"FOUR","","North-East-South-West (N-E-S-W) connectivity from given…",5,null],[13,"EIGHT","","N-NE-E-SE-S-SW-W-NW connectivity from given pixel/point",5,null],[4,"ConvMode","","Helps determine the size of output of convolution",null,null],[13,"DEFAULT","","Default convolution mode where output size is same as…",6,null],[13,"EXPAND","","Output of convolution is expanded based on signal and…",6,null],[4,"ConvDomain","","Helps determine if convolution is in Spatial or Frequency…",null,null],[13,"AUTO","","ArrayFire chooses whether the convolution will be in…",7,null],[13,"SPATIAL","","Convoltion in spatial domain",7,null],[13,"FREQUENCY","","Convolution in frequency domain",7,null],[4,"MatchType","","Error metric used by `matchTemplate` function",null,null],[13,"SAD","","Sum of Absolute Differences",8,null],[13,"ZSAD","","Zero-mean Sum of Absolute Differences",8,null],[13,"LSAD","","Locally scaled Sum of Absolute Differences",8,null],[13,"SSD","","Sum of Squared Differences",8,null],[13,"ZSSD","","Zero-mean Sum of Squared Differences",8,null],[13,"LSSD","","Localy scaled Sum of Squared Differences",8,null],[13,"NCC","","Normalized Cross Correlation",8,null],[13,"ZNCC","","Zero-mean Normalized Cross Correlation",8,null],[13,"SHD","","Sum of Hamming Distances",8,null],[4,"ColorSpace","","Identify the color space of given image(Array)",null,null],[13,"GRAY","","Grayscale color space",9,null],[13,"RGB","","Red-Green-Blue color space",9,null],[13,"HSV","","Hue-Saturation-value color space",9,null],[4,"MatProp","","Helps determine the type of a Matrix",null,null],[13,"NONE","","Default (no-op)",10,null],[13,"TRANS","","Data needs to be transposed",10,null],[13,"CTRANS","","Data needs to be conjugate transposed",10,null],[13,"CONJ","","Matrix is upper triangular",10,null],[13,"UPPER","","Matrix needs to be conjugate",10,null],[13,"LOWER","","Matrix is lower triangular",10,null],[13,"DIAGUNIT","","Matrix diagonal has unitary values",10,null],[13,"SYM","","Matrix is symmetric",10,null],[13,"POSDEF","","Matrix is positive definite",10,null],[13,"ORTHOG","","Matrix is orthogonal",10,null],[13,"TRIDIAG","","Matrix is tri-diagonal",10,null],[13,"BLOCKDIAG","","Matrix is block-diagonal",10,null],[4,"NormType","","Norm type",null,null],[13,"VECTOR_1","","Treats input as a vector and return sum of absolute values",11,null],[13,"VECTOR_INF","","Treats input as vector and return max of absolute values",11,null],[13,"VECTOR_2","","Treats input as vector and returns euclidean norm",11,null],[13,"VECTOR_P","","Treats input as vector and returns the p-norm",11,null],[13,"MATRIX_1","","Return the max of column sums",11,null],[13,"MATRIX_INF","","Return the max of row sums",11,null],[13,"MATRIX_2","","Returns the max singular value (Currently not supported)",11,null],[13,"MATRIX_L_PQ","","Returns Lpq-norm",11,null],[4,"ColorMap","","Dictates what color map is used for Image rendering",null,null],[13,"DEFAULT","","Default color map is grayscale range [0-1]",12,null],[13,"SPECTRUM","","Visible spectrum color map",12,null],[13,"COLORS","","Colors",12,null],[13,"RED","","Red hue map",12,null],[13,"MOOD","","Mood color map",12,null],[13,"HEAT","","Heat color map",12,null],[13,"BLUE","","Blue hue map",12,null],[4,"YCCStd","","YCbCr Standards",null,null],[13,"YCC_601","","ITU-R BT.601 (formerly CCIR 601) standard",13,null],[13,"YCC_709","","ITU-R BT.709 standard",13,null],[13,"YCC_2020","","ITU-R BT.2020 standard",13,null],[4,"HomographyType","","Homography type",null,null],[13,"RANSAC","","RANdom SAmple Consensus algorithm",14,null],[13,"LMEDS","","Least Median of Squares",14,null],[4,"MarkerType","","Plotting markers",null,null],[13,"NONE","","No marker",15,null],[13,"POINT","","Pointer marker",15,null],[13,"CIRCLE","","Hollow circle marker",15,null],[13,"SQUARE","","Hollow Square marker",15,null],[13,"TRIANGLE","","Hollow Triangle marker",15,null],[13,"CROSS","","Cross-hair marker",15,null],[13,"PLUS","","Plus symbol marker",15,null],[13,"STAR","","Start symbol marker",15,null],[4,"MomentType","","Image moment types",null,null],[13,"M00","","Central moment of order (0 + 0)",16,null],[13,"M01","","Central moment of order (0 + 1)",16,null],[13,"M10","","Central moment of order (1 + 0)",16,null],[13,"M11","","Central moment of order (1 + 1)",16,null],[13,"FIRST_ORDER","","All central moments of order (0,0), (0,1), (1,0) and (1,1)",16,null],[4,"SparseFormat","","Sparse storage format type",null,null],[13,"DENSE","","Dense format",17,null],[13,"CSR","","Compressed sparse row format",17,null],[13,"CSC","","Compressed sparse coloumn format",17,null],[13,"COO","","Coordinate list (row, coloumn, value) tuples.",17,null],[4,"BinaryOp","","Binary operation types for generalized scan functions",null,null],[13,"ADD","","Addition operation",18,null],[13,"MUL","","Multiplication operation",18,null],[13,"MIN","","Minimum operation",18,null],[13,"MAX","","Maximum operation",18,null],[4,"RandomEngineType","","Random engine types",null,null],[13,"PHILOX_4X32_10","","Philox variant with N=4, W=32 and Rounds=10",19,null],[13,"THREEFRY_2X32_16","","Threefry variant with N=2, W=32 and Rounds=16",19,null],[13,"MERSENNE_GP11213","","Mersenne variant with MEXP = 11213",19,null],[4,"Scalar","","Scalar value types",null,null],[13,"F32","","32 bit float",20,null],[13,"C32","","32 bit complex float",20,null],[13,"F64","","64 bit float",20,null],[13,"C64","","64 bit complex float",20,null],[13,"B8","","8 bit boolean",20,null],[13,"S32","","32 bit signed integer",20,null],[13,"U32","","32 bit unsigned integer",20,null],[13,"U8","","8 bit unsigned integer",20,null],[13,"S64","","64 bit signed integer",20,null],[13,"U64","","64 bit unsigned integer",20,null],[13,"S16","","16 bit signed integer",20,null],[13,"U16","","16 bit unsigned integer",20,null],[4,"CannyThresholdType","","Canny edge detector threshold operations types",null,null],[13,"MANUAL","","User has to define canny thresholds manually",21,null],[13,"OTSU","","Determine canny algorithm high threshold using Otsu…",21,null],[4,"DiffusionEq","","Anisotropic diffusion flux equation types",null,null],[13,"QUADRATIC","","Quadratic flux function",22,null],[13,"EXPONENTIAL","","Exponential flux function",22,null],[13,"DEFAULT","","Default flux function, a.k.a exponential",22,null],[4,"FluxFn","","Diffusion equation types",null,null],[13,"GRADIENT","","Quadratic flux function",23,null],[13,"MCDE","","Modified curvature diffusion equation",23,null],[13,"DEFAULT","","Default diffusion method, Gradient",23,null],[4,"TopkFn","","topk function ordering",null,null],[13,"MIN","","Top k min values",24,null],[13,"MAX","","Top k max values",24,null],[13,"DEFAULT","","Default option(max)",24,null],[4,"IterativeDeconvAlgo","","Iterative Deconvolution Algorithm",null,null],[13,"LANDWEBER","","Land-Weber Algorithm",25,null],[13,"RICHARDSONLUCY","","Richardson-Lucy Algorithm",25,null],[13,"DEFAULT","","Default is Land-Weber algorithm",25,null],[4,"InverseDeconvAlgo","","Inverse Deconvolution Algorithm",null,null],[13,"TIKHONOV","","Tikhonov algorithm",26,null],[13,"DEFAULT","","Default is Tikhonov algorithm",26,null],[4,"ConvGradientType","","Gradient mode for convolution",null,null],[13,"FILTER","","Filter Gradient",27,null],[13,"DATA","","Data Gradient",27,null],[13,"BIAS","","Biased Gradient",27,null],[13,"DEFAULT","","Default is Data Gradient",27,null],[4,"VarianceBias","","Gradient mode for convolution",null,null],[13,"SAMPLE","","Sample variance",28,null],[13,"POPULATION","","Population variance",28,null],[13,"DEFAULT","","Default (Population) variance",28,null],[4,"CublasMathMode","","Gradient mode for convolution",null,null],[13,"TENSOR_OP","","To indicate use of Tensor Cores on CUDA capable GPUs",29,null],[13,"DEFAULT","","Default i.e. tensor core operations will be avoided by the…",29,null],[5,"abs","","Computes absolute value",null,[[["array",3]],["array",3]]],[5,"arg","","Computes phase value",null,[[["array",3]],["array",3]]],[5,"trunc","","Truncate the values in an Array",null,[[["array",3]],["array",3]]],[5,"sign","","Computes the sign of input Array values",null,[[["array",3]],["array",3]]],[5,"round","","Round the values in an Array",null,[[["array",3]],["array",3]]],[5,"floor","","Floor the values in an Array",null,[[["array",3]],["array",3]]],[5,"ceil","","Ceil the values in an Array",null,[[["array",3]],["array",3]]],[5,"sigmoid","","Compute sigmoid function",null,[[["array",3]],["array",3]]],[5,"expm1","","Compute e raised to the power of value -1",null,[[["array",3]],["array",3]]],[5,"erf","","Compute error function value",null,[[["array",3]],["array",3]]],[5,"erfc","","Compute the complementary error function value",null,[[["array",3]],["array",3]]],[5,"log10","","Compute logarithm base 10",null,[[["array",3]],["array",3]]],[5,"log1p","","Compute the logarithm of input Array + 1",null,[[["array",3]],["array",3]]],[5,"log2","","Compute logarithm base 2",null,[[["array",3]],["array",3]]],[5,"cbrt","","Compute the cube root",null,[[["array",3]],["array",3]]],[5,"tgamma","","Compute gamma function",null,[[["array",3]],["array",3]]],[5,"lgamma","","Compute the logarithm of absolute values of gamma function",null,[[["array",3]],["array",3]]],[5,"acosh","","Compute acosh",null,[[["array",3]],["array",3]]],[5,"acos","","Compute acos",null,[[["array",3]],["array",3]]],[5,"asin","","Compute asin",null,[[["array",3]],["array",3]]],[5,"asinh","","Compute asinh",null,[[["array",3]],["array",3]]],[5,"atan","","Compute atan",null,[[["array",3]],["array",3]]],[5,"atanh","","Compute atanh",null,[[["array",3]],["array",3]]],[5,"cos","","Compute cos",null,[[["array",3]],["array",3]]],[5,"cosh","","Compute cosh",null,[[["array",3]],["array",3]]],[5,"exp","","Compute e raised to the power of value",null,[[["array",3]],["array",3]]],[5,"log","","Compute the natural logarithm",null,[[["array",3]],["array",3]]],[5,"sin","","Compute sin",null,[[["array",3]],["array",3]]],[5,"sinh","","Compute sinh",null,[[["array",3]],["array",3]]],[5,"sqrt","","Compute the square root",null,[[["array",3]],["array",3]]],[5,"rsqrt","","Compute the reciprocal square root",null,[[["array",3]],["array",3]]],[5,"tan","","Compute tan",null,[[["array",3]],["array",3]]],[5,"tanh","","Compute tanh",null,[[["array",3]],["array",3]]],[5,"real","","Extract real values from a complex Array",null,[[["array",3]],["array",3]]],[5,"imag","","Extract imaginary values from a complex Array",null,[[["array",3]],["array",3]]],[5,"cplx","","Create a complex Array from real Array",null,[[["array",3]],["array",3]]],[5,"conjg","","Compute the complex conjugate",null,[[["array",3]],["array",3]]],[5,"pow2","","Compute two raised to the power of value",null,[[["array",3]],["array",3]]],[5,"factorial","","Compute the factorial",null,[[["array",3]],["array",3]]],[5,"iszero","","Check if values are zero",null,[[["array",3]],["array",3]]],[5,"isinf","","Check if values are infinity",null,[[["array",3]],["array",3]]],[5,"isnan","","Check if values are NaN",null,[[["array",3]],["array",3]]],[5,"bitand","","Elementwise AND(bit) operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"bitor","","Elementwise OR(bit) operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"bitxor","","Elementwise XOR(bit) operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"neq","","Elementwise not equals comparison of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"and","","Elementwise logical and operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"or","","Elementwise logical or operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"minof","","Elementwise minimum operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"maxof","","Elementwise maximum operation of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"hypot","","Compute length of hypotenuse of two Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"add","","Addition of two Arrays",null,[[],["array",3]]],[5,"sub","","Subtraction of two Arrays",null,[[],["array",3]]],[5,"mul","","Multiplication of two Arrays",null,[[],["array",3]]],[5,"div","","Division of two Arrays",null,[[],["array",3]]],[5,"rem","","Compute remainder from two Arrays",null,[[],["array",3]]],[5,"shiftl","","Compute left shift",null,[[],["array",3]]],[5,"shiftr","","Compute right shift",null,[[],["array",3]]],[5,"modulo","","Compute modulo of two Arrays",null,[[],["array",3]]],[5,"atan2","","Calculate atan2 of two Arrays",null,[[],["array",3]]],[5,"cplx2","","Create complex array from two Arrays",null,[[],["array",3]]],[5,"root","","Compute root",null,[[],["array",3]]],[5,"pow","","Computer power",null,[[],["array",3]]],[5,"lt","","Perform `less than` comparison operation",null,[[],["array",3]]],[5,"gt","","Perform `greater than` comparison operation",null,[[],["array",3]]],[5,"le","","Perform `less than equals` comparison operation",null,[[],["array",3]]],[5,"ge","","Perform `greater than equals` comparison operation",null,[[],["array",3]]],[5,"eq","","Perform `equals` comparison operation",null,[[],["array",3]]],[5,"clamp","","Clamp the values of Array",null,[[["array",3]],["array",3]]],[5,"bitnot","","Perform bitwise complement on all values of Array",null,[[["array",3]],[["array",3],["hasafenum",8]]]],[5,"print","","Print data in the Array",null,[[["array",3]]]],[5,"print_gen","","Generalized Array print function",null,[[["option",4],["array",3],["string",3]]]],[5,"eval_multiple","","evaluate multiple arrays",null,[[["vec",3],["array",3]]]],[5,"set_manual_eval","","Set eval flag value",null,[[]]],[5,"is_eval_manual","","Get eval flag value",null,[[]]],[5,"set_backend","","Toggle backends between cuda, opencl or cpu",null,[[["backend",4]]]],[5,"get_backend_count","","Get the available backend count",null,[[]]],[5,"get_available_backends","","Get the available backends",null,[[],[["vec",3],["backend",4]]]],[5,"get_active_backend","","Get current active backend",null,[[],["backend",4]]],[5,"constant","","Create an Array with constant value",null,[[["dim4",3]],["array",3]]],[5,"range","","Create a Range of values",null,[[["dim4",3]],[["array",3],["hasafenum",8]]]],[5,"iota","","Create a range of values",null,[[["dim4",3]],[["array",3],["hasafenum",8]]]],[5,"identity","","Create an identity array with 1\'s in diagonal",null,[[["dim4",3]],[["array",3],["hasafenum",8]]]],[5,"diag_create","","Create a diagonal matrix",null,[[["array",3]],["array",3]]],[5,"diag_extract","","Extract diagonal from a given Matrix",null,[[["array",3]],["array",3]]],[5,"join","","Join two arrays",null,[[["array",3]],["array",3]]],[5,"join_many","","Join multiple arrays",null,[[["vec",3],["array",3]],["array",3]]],[5,"tile","","Tile the input array along specified dimension",null,[[["array",3],["dim4",3]],["array",3]]],[5,"reorder_v2","","Reorder the array according to the new specified axes",null,[[["vec",3],["array",3],["option",4]],["array",3]]],[5,"reorder","","Reorder the array in specified order",null,[[["array",3],["dim4",3]],["array",3]]],[5,"shift","","\\\"Circular shift of values along specified dimension",null,[[["array",3]],["array",3]]],[5,"moddims","","Change the shape of the Array",null,[[["array",3],["dim4",3]],["array",3]]],[5,"flat","","Flatten the multidimensional Array to an 1D Array",null,[[["array",3]],["array",3]]],[5,"flip","","Flip the Array",null,[[["array",3]],["array",3]]],[5,"lower","","Create lower triangular matrix",null,[[["array",3]],["array",3]]],[5,"upper","","Create upper triangular matrix",null,[[["array",3]],["array",3]]],[5,"select","","Element wise conditional operator for Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"selectl","","Element wise conditional operator for Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"selectr","","Element wise conditional operator for Arrays",null,[[["array",3],["array",3]],["array",3]]],[5,"replace","","Inplace replace in Array based on a condition",null,[[["array",3],["array",3],["array",3]]]],[5,"replace_scalar","","Inplace replace in Array based on a condition",null,[[["array",3],["array",3]]]],[5,"pad","","Pad input Array along borders",null,[[["array",3],["bordertype",4],["dim4",3]],[["array",3],["hasafenum",8]]]],[5,"get_version","","Get ArrayFire Version Number",null,[[]]],[5,"get_revision","","Get ArrayFire Revision (commit) information of the library.",null,[[],["cow",4]]],[5,"info","","Print library meta-info",null,[[]]],[5,"info_string","","Return library meta-info as `String`",null,[[],["string",3]]],[5,"device_info","","Gets the information about device and platform as strings.",null,[[]]],[5,"init","","Initialize ArrayFire library",null,[[]]],[5,"device_count","","Get total number of available devices",null,[[]]],[5,"is_double_available","","Check if a device has double support",null,[[]]],[5,"set_device","","Set active device",null,[[]]],[5,"get_device","","Get the current active device id",null,[[]]],[5,"device_mem_info","","Get memory information from the memory manager for the…",null,[[]]],[5,"print_mem_info","","Print buffer details from the ArrayFire device manager",null,[[["string",3]]]],[5,"set_mem_step_size","","Set the minimum memory chunk size",null,[[]]],[5,"get_mem_step_size","","Get the minimum memory chunk size",null,[[]]],[5,"device_gc","","Call the garbage collection routine",null,[[]]],[5,"sync","","Sync all operations on given device",null,[[]]],[5,"alloc_pinned","","Allocate non-pageable memory on HOST memory",null,[[],["void_ptr",6]]],[5,"free_pinned","","Free the pointer returned by alloc_pinned",null,[[["void_ptr",6]]]],[5,"is_half_available","","Check if a device has half support",null,[[]]],[5,"handle_error_general","","Default error handling callback provided by ArrayFire crate",null,[[["aferror",4]]]],[5,"register_error_handler","","Register user provided error handler",null,[[["callback",3]]]],[5,"HANDLE_ERROR","","Default error handler for error code returned by ArrayFire…",null,[[["aferror",4]]]],[5,"get_last_error","","Fetch last error description as String",null,[[],["string",3]]],[5,"index","","Indexes the `input` Array using `seqs` Sequences",null,[[["array",3]],["array",3]]],[5,"row","","Extract `row_num` row from `input` Array",null,[[["array",3]],["array",3]]],[5,"set_row","","Set `row_num`^th row in `inout` Array to a new Array…",null,[[["array",3],["array",3]]]],[5,"rows","","Get an Array with all rows from `first` to `last` in the…",null,[[["array",3]],["array",3]]],[5,"set_rows","","Set rows from `first` to `last` in `inout` Array with rows…",null,[[["array",3],["array",3]]]],[5,"col","","Extract `col_num` col from `input` Array",null,[[["array",3]],["array",3]]],[5,"set_col","","Set `col_num`^th col in `inout` Array to a new Array…",null,[[["array",3],["array",3]]]],[5,"cols","","Get all cols from `first` to `last` in the `input` Array",null,[[["array",3]],["array",3]]],[5,"set_cols","","Set cols from `first` to `last` in `inout` Array with cols…",null,[[["array",3],["array",3]]]],[5,"slice","","Get `slice_num`^th slice from `input` Array",null,[[["array",3]],["array",3]]],[5,"set_slice","","Set slice `slice_num` in `inout` Array to a new Array…",null,[[["array",3],["array",3]]]],[5,"slices","","Get slices from `first` to `last` in `input` Array",null,[[["array",3]],["array",3]]],[5,"set_slices","","Set `first` to `last` slices of `inout` Array to a new…",null,[[["array",3],["array",3]]]],[5,"lookup","","Lookup(hash) an Array using another Array",null,[[["array",3],["array",3]],["array",3]]],[5,"assign_seq","","Assign(copy) content of an Array to another Array indexed…",null,[[["array",3],["array",3]]]],[5,"index_gen","","Index an Array using any combination of Array\'s and…",null,[[["indexer",3],["array",3]],["array",3]]],[5,"assign_gen","","Assign an Array to another after indexing it using any…",null,[[["array",3],["indexer",3],["array",3]]]],[5,"set_seed","","Set seed for random number generation",null,[[]]],[5,"get_seed","","Get the seed of random number generator",null,[[]]],[5,"randu","","Create random numbers from uniform distribution",null,[[["dim4",3]],["array",3]]],[5,"randn","","Create random numbers from normal distribution",null,[[["dim4",3]],["array",3]]],[5,"get_default_random_engine","","Get default random engine",null,[[],["randomengine",3]]],[5,"set_default_random_engine_type","","Set the random engine type for default random number…",null,[[["randomenginetype",4]]]],[5,"random_uniform","","Generate array of uniform numbers using a random engine",null,[[["randomengine",3],["dim4",3]],["array",3]]],[5,"random_normal","","Generate array of normal numbers using a random engine",null,[[["randomengine",3],["dim4",3]],["array",3]]],[5,"get_size","","Get size, in bytes, of the arrayfire native type",null,[[["dtype",4]]]],[5,"alloc_host","","Allocates space using Arrayfire allocator in host memory",null,[[["dtype",4]]]],[5,"free_host","","Frees memory allocated by Arrayfire allocator in host memory",null,[[]]],[5,"sum","","Sum elements along a given dimension",null,[[["array",3]],["array",3]]],[5,"product","","Compute product of elements along a given dimension",null,[[["array",3]],["array",3]]],[5,"min","","Find minimum among elements of given dimension",null,[[["array",3]],["array",3]]],[5,"max","","Find maximum among elements of given dimension",null,[[["array",3]],["array",3]]],[5,"all_true","","Find if all of the values along a given dimension in the…",null,[[["array",3]],["array",3]]],[5,"any_true","","Find if any of the values along a given dimension in the…",null,[[["array",3]],["array",3]]],[5,"count","","Count number of non-zero elements along a given dimension",null,[[["array",3]],["array",3]]],[5,"accum","","Perform exclusive sum of elements along a given dimension",null,[[["array",3]],["array",3]]],[5,"diff1","","Calculate first order numerical difference along a given…",null,[[["array",3]],["array",3]]],[5,"diff2","","Calculate second order numerical difference along a given…",null,[[["array",3]],["array",3]]],[5,"sum_nan","","Sum along specific dimension using user specified value…",null,[[["array",3]],["array",3]]],[5,"product_nan","","Product of elements along specific dimension using user…",null,[[["array",3]],["array",3]]],[5,"sum_all","","Sum all values of the Array",null,[[["array",3]]]],[5,"product_all","","Product of all values of the Array",null,[[["array",3]]]],[5,"min_all","","Find minimum among all values of the Array",null,[[["array",3]]]],[5,"max_all","","Find maximum among all values of the Array",null,[[["array",3]]]],[5,"all_true_all","","Find if all values of Array are non-zero",null,[[["array",3]]]],[5,"any_true_all","","Find if any value of Array is non-zero",null,[[["array",3]]]],[5,"count_all","","Count number of non-zero values in the Array",null,[[["array",3]]]],[5,"sum_nan_all","","Sum all values using user provided value for `NAN`",null,[[["array",3]]]],[5,"product_nan_all","","Product of all values using user provided value for `NAN`",null,[[["array",3]]]],[5,"imin","","Find minimum value along given dimension and their…",null,[[["array",3]]]],[5,"imax","","Find maximum value along given dimension and their…",null,[[["array",3]]]],[5,"imin_all","","Find minimum and it\'s index in the whole Array",null,[[["array",3]]]],[5,"imax_all","","Find maximum and it\'s index in the whole Array",null,[[["array",3]]]],[5,"locate","","Locate the indices of non-zero elements.",null,[[["array",3]],["array",3]]],[5,"sort","","Sort the values in input Arrays",null,[[["array",3]],["array",3]]],[5,"sort_index","","Sort the values in input Arrays",null,[[["array",3]]]],[5,"sort_by_key","","Sort the values in input Arrays",null,[[["array",3],["array",3]]]],[5,"set_unique","","Find unique values from a Set",null,[[["array",3]],["array",3]]],[5,"set_union","","Find union of two sets",null,[[["array",3]],["array",3]]],[5,"set_intersect","","Find intersection of two sets",null,[[["array",3]],["array",3]]],[5,"scan","","Generalized scan",null,[[["binaryop",4],["array",3]],["array",3]]],[5,"scan_by_key","","Generalized scan by key",null,[[["binaryop",4],["array",3],["array",3]],["array",3]]],[5,"all_true_by_key","","Key based AND of elements along a given dimension",null,[[["array",3],["array",3]]]],[5,"any_true_by_key","","Key based OR of elements along a given dimension",null,[[["array",3],["array",3]]]],[5,"count_by_key","","Find total count of elements with similar keys along a…",null,[[["array",3],["array",3]]]],[5,"max_by_key","","Find maximum among values of similar keys along a given…",null,[[["array",3],["array",3]]]],[5,"min_by_key","","Find minimum among values of similar keys along a given…",null,[[["array",3],["array",3]]]],[5,"product_by_key","","Find product of all values with similar keys along a given…",null,[[["array",3],["array",3]]]],[5,"sum_by_key","","Find sum of all values with similar keys along a given…",null,[[["array",3],["array",3]]]],[5,"sum_by_key_nan","","Compute sum of all values with similar keys along a given…",null,[[["array",3],["array",3]]]],[5,"product_by_key_nan","","Compute product of all values with similar keys along a…",null,[[["array",3],["array",3]]]],[5,"max_ragged","","Max reduction along given axis as per ragged lengths…",null,[[["array",3],["array",3]]]],[5,"gemm","","BLAS general matrix multiply (GEMM) of two Array objects",null,[[["array",3],["matprop",4],["array",3],["vec",3]]]],[5,"matmul","","Matrix multiple of two Arrays",null,[[["matprop",4],["array",3]],["array",3]]],[5,"dot","","Calculate the dot product of vectors.",null,[[["matprop",4],["array",3]],["array",3]]],[5,"transpose","","Transpose of a matrix.",null,[[["array",3]],[["array",3],["hasafenum",8]]]],[5,"transpose_inplace","","Inplace transpose of a matrix.",null,[[["array",3]]]],[5,"set_cublas_mode","","Sets the cuBLAS math mode for the internal handle.",null,[[["cublasmathmode",4]]]],[5,"gradient","","Calculate the gradients",null,[[["array",3]]]],[5,"load_image","","Load Image into Array",null,[[["string",3]],["array",3]]],[5,"load_image_native","","Load Image into Array in it\'s native type",null,[[["string",3]],["array",3]]],[5,"save_image","","Save an Array to an image file",null,[[["array",3],["string",3]]]],[5,"save_image_native","","Save an Array without modifications to an image file",null,[[["array",3],["string",3]]]],[5,"resize","","Resize an Image",null,[[["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"transform","","Transform(Affine) an Image",null,[[["array",3],["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"rotate","","Rotate an Image",null,[[["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"translate","","Translate an Image",null,[[["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"scale","","Scale an Image",null,[[["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"skew","","Skew an image",null,[[["array",3],["interptype",4]],[["array",3],["hasafenum",8]]]],[5,"histogram","","Compute Histogram of an Array",null,[[["array",3]],["array",3]]],[5,"dilate","","Dilate an Image",null,[[["array",3]],["array",3]]],[5,"erode","","Erode an Image",null,[[["array",3]],["array",3]]],[5,"dilate3","","Dilate a Volume",null,[[["array",3]],["array",3]]],[5,"erode3","","Erode a Volume",null,[[["array",3]],["array",3]]],[5,"bilateral","","Bilateral Filter.",null,[[["array",3]],["array",3]]],[5,"mean_shift","","Meanshift Filter.",null,[[["array",3]],["array",3]]],[5,"medfilt","","Median filter",null,[[["array",3],["bordertype",4]],["array",3]]],[5,"minfilt","","Box filter with minimum as box operation",null,[[["array",3],["bordertype",4]],["array",3]]],[5,"maxfilt","","Box filter with maximum as box operation",null,[[["array",3],["bordertype",4]],["array",3]]],[5,"gaussian_kernel","","Creates a Gaussian Kernel.",null,[[],["array",3]]],[5,"color_space","","Color space conversion",null,[[["array",3],["colorspace",4]],["array",3]]],[5,"regions","","Find blobs in given image.",null,[[["array",3],["connectivity",4]],["array",3]]],[5,"sobel","","Sobel Operator",null,[[["array",3]]]],[5,"hist_equal","","Histogram Equalization",null,[[["array",3],["array",3]],["array",3]]],[5,"rgb2gray","","Color(RGB) to Grayscale conversion",null,[[["array",3]],["array",3]]],[5,"gray2rgb","","Grayscale to Color(RGB) conversion",null,[[["array",3]],["array",3]]],[5,"hsv2rgb","","HSV to RGB color space conversion",null,[[["array",3]],["array",3]]],[5,"rgb2hsv","","RGB to HSV color space conversion",null,[[["array",3]],["array",3]]],[5,"unwrap","","Generate an array with image windows as columns",null,[[["array",3]],[["array",3],["hasafenum",8]]]],[5,"wrap","","Converts unwrapped image to an image",null,[[["array",3]],[["array",3],["hasafenum",8]]]],[5,"sat","","Summed area table of an Image",null,[[["array",3]],["array",3]]],[5,"rgb2ycbcr","","RGB to YCbCr colorspace converter.",null,[[["array",3],["yccstd",4]],["array",3]]],[5,"ycbcr2rgb","","YCbCr to RGB colorspace converter.",null,[[["array",3],["yccstd",4]],["array",3]]],[5,"is_imageio_available","","Function to check if Image I/O is available",null,[[]]],[5,"transform_coords","","Transform input coordinates",null,[[["array",3]],["array",3]]],[5,"moments","","Find Image moments",null,[[["momenttype",4],["array",3]],["array",3]]],[5,"moments_all","","Find Image moment for whole image",null,[[["momenttype",4],["array",3]]]],[5,"medfilt1","","One dimensional median filter on image",null,[[["array",3],["bordertype",4]],["array",3]]],[5,"canny","","Canny edge detection operator",null,[[["array",3],["cannythresholdtype",4]],["array",3]]],[5,"anisotropic_diffusion","","Anisotropic smoothing filter",null,[[["diffusioneq",4],["array",3],["fluxfn",4]],["array",3]]],[5,"confidence_cc","","Segment image based on similar pixel characteristics",null,[[["array",3],["array",3]],["array",3]]],[5,"iterative_deconv","","Iterative Deconvolution",null,[[["array",3],["array",3],["iterativedeconvalgo",4]],["array",3]]],[5,"inverse_deconv","","Inverse deconvolution",null,[[["array",3],["array",3],["inversedeconvalgo",4]],["array",3]]],[5,"svd","","Perform Singular Value Decomposition",null,[[["array",3]]]],[5,"svd_inplace","","Perform Singular Value Decomposition inplace",null,[[["array",3]]]],[5,"lu","","Perform LU decomposition",null,[[["array",3]]]],[5,"lu_inplace","","Perform inplace LU decomposition",null,[[["array",3]],["array",3]]],[5,"qr","","Perform QR decomposition",null,[[["array",3]]]],[5,"qr_inplace","","Perform inplace QR decomposition",null,[[["array",3]],["array",3]]],[5,"cholesky","","Perform Cholesky decomposition",null,[[["array",3]]]],[5,"cholesky_inplace","","Perform inplace Cholesky decomposition",null,[[["array",3]]]],[5,"solve","","Solve a system of equations",null,[[["matprop",4],["array",3]],["array",3]]],[5,"solve_lu","","Solve a system of equations",null,[[["matprop",4],["array",3],["array",3]],["array",3]]],[5,"inverse","","Compute inverse of a matrix",null,[[["matprop",4],["array",3]],["array",3]]],[5,"rank","","Find rank of a matrix",null,[[["array",3]]]],[5,"det","","Find the determinant of the matrix",null,[[["array",3]]]],[5,"norm","","Find the norm of a matrix",null,[[["array",3],["normtype",4]]]],[5,"is_lapack_available","","Function to check if lapack support is available",null,[[]]],[5,"pinverse","","Psuedo Inverse of Matrix",null,[[["matprop",4],["array",3]],["array",3]]],[5,"convolve2_nn","","Convolution Integral for two dimensional data",null,[[["array",3],["dim4",3]],["array",3]]],[5,"convolve2_gradient_nn","","Backward pass gradient of 2D convolution",null,[[["convgradienttype",4],["array",3],["dim4",3]],["array",3]]],[5,"approx1","","Perform signal interpolation for 1d signals",null,[[["interptype",4],["array",3],["array",3]],["array",3]]],[5,"approx1_v2","","Same as approx1 but uses existing Array as output",null,[[["array",3],["array",3],["interptype",4],["array",3]]]],[5,"approx1_uniform","","Perform signal interpolation for 1d signals along…",null,[[["interptype",4],["array",3],["array",3]],["array",3]]],[5,"approx1_uniform_v2","","Same as approx1_uniform but uses existing Array as output",null,[[["array",3],["array",3],["interptype",4],["array",3]]]],[5,"approx2","","Perform signal interpolation for 2d signals",null,[[["interptype",4],["array",3],["array",3]],["array",3]]],[5,"approx2_v2","","Same as approx2 but uses existing Array as output",null,[[["array",3],["array",3],["interptype",4],["array",3]]]],[5,"approx2_uniform","","Perform signal interpolation for 2d signals along a…",null,[[["interptype",4],["array",3],["array",3]],["array",3]]],[5,"approx2_uniform_v2","","Same as approx2_uniform but uses existing Array as output",null,[[["array",3],["array",3],["interptype",4],["array",3]]]],[5,"set_fft_plan_cache_size","","Set fft plan cache size",null,[[]]],[5,"fft","","Fast fourier transform for 1d signals",null,[[["array",3]],["array",3]]],[5,"fft2","","Fast fourier transform for 2d signals",null,[[["array",3]],["array",3]]],[5,"fft3","","Fast fourier transform for 3d signals",null,[[["array",3]],["array",3]]],[5,"ifft","","Inverse fast fourier transform for 1d signals",null,[[["array",3]],["array",3]]],[5,"ifft2","","Inverse fast fourier transform for 2d signals",null,[[["array",3]],["array",3]]],[5,"ifft3","","Inverse fast fourier transform for 3d signals",null,[[["array",3]],["array",3]]],[5,"convolve1","","1d convolution",null,[[["convmode",4],["array",3],["convdomain",4],["array",3]],["array",3]]],[5,"convolve2","","2d convolution",null,[[["convmode",4],["array",3],["convdomain",4],["array",3]],["array",3]]],[5,"convolve3","","3d convolution",null,[[["convmode",4],["array",3],["convdomain",4],["array",3]],["array",3]]],[5,"convolve2_sep","","Separable convolution for 2d signals",null,[[["convmode",4],["array",3],["array",3]],["array",3]]],[5,"fft_convolve1","","1d convolution using fast-fourier transform",null,[[["convmode",4],["array",3],["array",3]],["array",3]]],[5,"fft_convolve2","","2d convolution using fast-fourier transform",null,[[["convmode",4],["array",3],["array",3]],["array",3]]],[5,"fft_convolve3","","3d convolution using fast-fourier transform",null,[[["convmode",4],["array",3],["array",3]],["array",3]]],[5,"fir","","Finite impulse filter",null,[[["array",3],["array",3]],["array",3]]],[5,"iir","","Infinite impulse response filter",null,[[["array",3]],[["array",3],["hasafenum",8]]]],[5,"fft_inplace","","In place 1d dimensional Fast fourier transform",null,[[["array",3]]]],[5,"fft2_inplace","","In place 2d dimensional Fast fourier transform",null,[[["array",3]]]],[5,"fft3_inplace","","In place 3d dimensional Fast fourier transform",null,[[["array",3]]]],[5,"ifft_inplace","","In place 1d dimensional inverse fast fourier transform",null,[[["array",3]]]],[5,"ifft2_inplace","","In place 2d dimensional inverse fast fourier transform",null,[[["array",3]]]],[5,"ifft3_inplace","","In place 3d dimensional inverse fast fourier transform",null,[[["array",3]]]],[5,"fft_r2c","","1d Real to Complex fast fourier transform",null,[[["array",3]],[["array",3],["complex",3]]]],[5,"fft2_r2c","","2d Real to Complex fast fourier transform",null,[[["array",3]],[["array",3],["complex",3]]]],[5,"fft3_r2c","","3d Real to Complex fast fourier transform",null,[[["array",3]],[["array",3],["complex",3]]]],[5,"fft_c2r","","1d Complex to Real fast fourier transform",null,[[["array",3]],["array",3]]],[5,"fft2_c2r","","2d Complex to Real fast fourier transform",null,[[["array",3]],["array",3]]],[5,"fft3_c2r","","3d Complex to Real fast fourier transform",null,[[["array",3]],["array",3]]],[5,"sparse","","Create sprase matrix from arrays",null,[[["array",3],["sparseformat",4],["array",3]],["array",3]]],[5,"sparse_from_host","","Create sprase matrix from data on host memory",null,[[["sparseformat",4]],["array",3]]],[5,"sparse_from_dense","","Convert dense array to sparse array",null,[[["array",3],["sparseformat",4]],["array",3]]],[5,"sparse_convert_to","","Convert between sparse formats",null,[[["array",3],["sparseformat",4]],["array",3]]],[5,"sparse_to_dense","","Convert sparse array to dense array",null,[[["array",3]],["array",3]]],[5,"sparse_get_info","","Get sparse Array information",null,[[["array",3]]]],[5,"sparse_get_values","","Get values of sparse Array",null,[[["array",3]],["array",3]]],[5,"sparse_get_row_indices","","Get row indices Array",null,[[["array",3]],["array",3]]],[5,"sparse_get_col_indices","","Get cololumn indices Array",null,[[["array",3]],["array",3]]],[5,"sparse_get_nnz","","Get number of non-zero elements in sparse array",null,[[["array",3]]]],[5,"sparse_get_format","","Get sparse format",null,[[["array",3]],["sparseformat",4]]],[5,"median","","Find the median along a given dimension",null,[[["array",3]],["array",3]]],[5,"mean","","Mean along specified dimension",null,[[["array",3]],["array",3]]],[5,"mean_weighted","","Weighted mean along specified dimension",null,[[["array",3],["array",3]],["array",3]]],[5,"var_weighted","","Weight variance along specified dimension",null,[[["array",3],["array",3]],["array",3]]],[5,"var_v2","","Compute Variance along a specific dimension",null,[[["array",3],["variancebias",4]],["array",3]]],[5,"var","","Compute Variance along a specific dimension",null,[[["array",3]],["array",3]]],[5,"cov_v2","","Compute covariance of two Arrays",null,[[["array",3],["variancebias",4]],["array",3]]],[5,"cov","","Compute covariance of two Arrays",null,[[["array",3]],["array",3]]],[5,"var_all_v2","","Compute Variance of all elements",null,[[["array",3],["variancebias",4]]]],[5,"var_all","","Compute Variance of all elements",null,[[["array",3]]]],[5,"mean_all","","Compute mean of all data",null,[[["array",3]]]],[5,"median_all","","Compute median of all data",null,[[["array",3]]]],[5,"mean_all_weighted","","Compute weighted mean of all data",null,[[["array",3],["array",3]]]],[5,"var_all_weighted","","Compute weighted variance of all data",null,[[["array",3],["array",3]]]],[5,"corrcoef","","Compute correlation coefficient",null,[[["array",3]]]],[5,"topk","","Find top k elements along a given dimension",null,[[["array",3],["topkfn",4]]]],[5,"meanvar","","Calculate mean and variance in single API call",null,[[["array",3],["array",3],["variancebias",4]]]],[5,"stdev_v2","","Standard deviation along given axis",null,[[["array",3],["variancebias",4]],["array",3]]],[5,"stdev","","Standard deviation along specified axis",null,[[["array",3]],["array",3]]],[5,"stdev_all_v2","","Compute standard deviation of all data",null,[[["array",3],["variancebias",4]]]],[5,"stdev_all","","Compute standard deviation of all data",null,[[["array",3]]]],[5,"fast","","Fast feature detector",null,[[["array",3]],["features",3]]],[5,"harris","","Harris corner detector.",null,[[["array",3]],["features",3]]],[5,"orb","","ORB feature descriptor",null,[[["array",3]]]],[5,"hamming_matcher","","Hamming feature matcher",null,[[["array",3]]]],[5,"nearest_neighbour","","Nearest Neighbour.",null,[[["matchtype",4],["array",3]]]],[5,"match_template","","Image matching",null,[[["matchtype",4],["array",3]],["array",3]]],[5,"susan","","SUSAN corner detector.",null,[[["array",3]],["features",3]]],[5,"dog","","Difference of Gaussians.",null,[[["array",3]],["array",3]]],[5,"homography","","Homography estimation",null,[[["array",3],["homographytype",4]]]],[11,"new","","Constructs a new Array object",30,[[["dim4",3]]]],[11,"new_strided","","Constructs a new Array object from strided data",30,[[["dim4",3]]]],[11,"new_empty","","Constructs a new Array object of specified dimensions and…",30,[[["dim4",3]]]],[11,"new_from_device_ptr","","Constructs a new Array object from device pointer",30,[[["dim4",3]]]],[11,"get_backend","","Returns the backend of the Array",30,[[],["backend",4]]],[11,"get_device_id","","Returns the device identifier(integer) on which the Array…",30,[[]]],[11,"elements","","Returns the number of elements in the Array",30,[[]]],[11,"get_type","","Returns the Array data type",30,[[],["dtype",4]]],[11,"dims","","Returns the dimensions of the Array",30,[[],["dim4",3]]],[11,"strides","","Returns the strides of the Array",30,[[],["dim4",3]]],[11,"numdims","","Returns the number of dimensions of the Array",30,[[]]],[11,"offset","","Returns the offset to the pointer from where data begins",30,[[]]],[11,"get","","Returns the native FFI handle for Rust object `Array`",30,[[],["af_array",6]]],[11,"set","","Set the native FFI handle for Rust object `Array`",30,[[["af_array",6]]]],[11,"host","","Copies the data from the Array to the mutable slice `data`",30,[[]]],[11,"eval","","Evaluates any pending lazy expressions that represent the…",30,[[]]],[11,"copy","","Makes an copy of the Array",30,[[]]],[11,"is_empty","","Check if Array is empty",30,[[]]],[11,"is_scalar","","Check if Array is scalar",30,[[]]],[11,"is_row","","Check if Array is a row",30,[[]]],[11,"is_column","","Check if Array is a column",30,[[]]],[11,"is_vector","","Check if Array is a vector",30,[[]]],[11,"is_real","","Check if Array is of real (not complex) type",30,[[]]],[11,"is_complex","","Check if Array is of complex type",30,[[]]],[11,"is_double","","Check if Array\'s numerical type is of double precision",30,[[]]],[11,"is_single","","Check if Array\'s numerical type is of single precision",30,[[]]],[11,"is_half","","Check if Array\'s numerical type is of half precision",30,[[]]],[11,"is_integer","","Check if Array is of integral type",30,[[]]],[11,"is_bool","","Check if Array is of boolean type",30,[[]]],[11,"is_realfloating","","Check if Array is floating point real(not complex) data type",30,[[]]],[11,"is_floating","","Check if Array is floating point type, either real or…",30,[[]]],[11,"is_linear","","Check if Array\'s memory layout is continuous and one…",30,[[]]],[11,"is_sparse","","Check if Array is a sparse matrix",30,[[]]],[11,"is_owner","","Check if Array\'s memory is owned by it and not a view of…",30,[[]]],[11,"cast","","Cast the Array data type to `target_type`",30,[[],[["array",3],["hasafenum",8]]]],[11,"lock","","Lock the device buffer in the memory manager",30,[[]]],[11,"unlock","","Unlock the device buffer in the memory manager",30,[[]]],[11,"device_ptr","","Get the device pointer and lock the buffer in memory manager",30,[[],["void_ptr",6]]],[11,"get_allocated_bytes","","Get the size of physical allocated bytes.",30,[[]]],[11,"new","","Create Dim4 object",31,[[]]],[11,"elements","","Get the number of elements represented by Dim4 object",31,[[]]],[11,"ndims","","Get the number of dimensions of Dim4",31,[[]]],[11,"get","","Get the dimensions as a slice of 4 values",31,[[]]],[11,"new","","Associated function to create a new Callback object",32,[[["errorcallback",6]]]],[11,"call","","call invokes the error callback with `error_code`.",32,[[["aferror",4]]]],[11,"mark","","Marks the event on the active computation queue.",33,[[]]],[11,"enqueue_wait","","Enqueues the event and all enqueued events on the active…",33,[[]]],[11,"block","","Blocks the calling thread on events until all events on…",33,[[]]],[11,"new","","Create a new Indexer object and set the dimension specific…",34,[[]]],[11,"set_index","","Set either Array or Seq to index an Array along `idx`…",34,[[["option",4]]]],[11,"len","","Get number of indexing objects set",34,[[]]],[11,"is_empty","","Check if any indexing objects are set",34,[[]]],[11,"get","","Get native(ArrayFire) resource handle",34,[[],["af_index_t",6]]],[11,"new","","Create a new random engine object",35,[[["option",4],["randomenginetype",4]]]],[11,"get_type","","Get random engine type",35,[[],["randomenginetype",4]]],[11,"set_type","","Get random engine type",35,[[["randomenginetype",4]]]],[11,"set_seed","","Set seed for random engine",35,[[]]],[11,"get_seed","","Get seed of the random engine",35,[[]]],[11,"get","","Returns the native FFI handle for Rust object `RandomEngine`",35,[[],["af_random_engine",6]]],[11,"new","","Create a `Seq` that goes from `begin` to `end` at a step…",36,[[]]],[11,"begin","","Get begin index of Seq",36,[[]]],[11,"end","","Get end index of Seq",36,[[]]],[11,"step","","Get step size of Seq",36,[[]]],[11,"new","","Creates new Window object",37,[[["string",3]]]],[11,"set_position","","Set window starting position on the screen",37,[[]]],[11,"set_title","","Set window title",37,[[["string",3]]]],[11,"set_visibility","","Set window visibility",37,[[]]],[11,"set_size","","Set window size",37,[[]]],[11,"set_colormap","","Set color map to be used for rendering image, it can take…",37,[[["colormap",4]]]],[11,"is_closed","","Returns true if the window close is triggered by the user",37,[[]]],[11,"grid","","Setup display layout in multiview mode",37,[[]]],[11,"show","","Used in multiview mode to swap back buffer with front…",37,[[]]],[11,"set_view","","Set the current sub-region to render",37,[[]]],[11,"set_axes_titles","","Set chart axes titles",37,[[["string",3]]]],[11,"set_axes_label_format","","Set chart axes labels format",37,[[["string",3]]]],[11,"set_axes_label_formats","","Set chart axes labels formats",37,[[["string",3]]]],[11,"set_axes_limits_compute","","Set chart axes limits by computing limits from data",37,[[["array",3],["option",4]]]],[11,"set_axes_limits_2d","","Set 2d chart axes limits",37,[[]]],[11,"set_axes_limits_3d","","Set 3d chart axes limits",37,[[]]],[11,"draw_image","","Render given Array as an image",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_plot2","","Render given two Array\'s `x` and `y` as a 2d line plot",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_plot3","","Render given Array\'s `x`, `y` and `z` as a 3d line plot",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_plot","","Render give Arrays of points as a 3d line plot",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_hist","","Render given Array as a histogram",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_surface","","Render give Arrays as 3d surface",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_scatter2","","Render given Arrays as 2d scatter plot",37,[[["markertype",4],["array",3],["string",3],["option",4]]]],[11,"draw_scatter3","","Render given Arrays as 3d scatter plot",37,[[["markertype",4],["array",3],["string",3],["option",4]]]],[11,"draw_scatter","","Render give Array as 3d scatter plot",37,[[["markertype",4],["array",3],["string",3],["option",4]]]],[11,"draw_vector_field2","","Render given Arrays as 2d vector field",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_vector_field3","","Render given Arrays as 3d vector field",37,[[["option",4],["array",3],["string",3]]]],[11,"draw_vector_field","","Render given Array as vector field",37,[[["option",4],["array",3],["string",3]]]],[11,"new","","Create and return an object of type Features",38,[[]]],[11,"num_features","","Get total number of features found",38,[[]]],[11,"xpos","","Get x coordinates Array",38,[[],["array",3]]],[11,"ypos","","Get y coordinates Array",38,[[],["array",3]]],[11,"score","","Get score Array",38,[[],["array",3]]],[11,"orientation","","Get orientation Array",38,[[],["array",3]]],[11,"size","","Get features size Array",38,[[],["array",3]]],[11,"get","","Get the internal handle for Features object",38,[[],["af_features",6]]],[6,"ErrorCallback","","Signature of error handling callback function",null,null],[6,"c32","","Short type alias for Complex single precision type",null,null],[6,"c64","","Short type alias for Complex double precision type",null,null],[6,"dim_t","","ArrayFire FFI Type alias for libc\'s signed long long",null,null],[6,"u64_t","","ArrayFire FFI Type alias for libc\'s unsigned long long",null,null],[6,"void_ptr","","ArrayFire FFI Type alias for libc\'s void*",null,null],[6,"af_array","","ArrayFire FFI Type alias for af_array",null,null],[6,"af_event","","ArrayFire FFI Type alias for af_event",null,null],[6,"af_index_t","","ArrayFire FFI Type alias for af_indexers_t",null,null],[6,"af_features","","ArrayFire FFI Type alias for af_features",null,null],[6,"af_random_engine","","ArrayFire FFI Type alias for af_random_engine",null,null],[6,"af_window","","ArrayFire FFI Type alias for af_window",null,null],[17,"PHILOX","","Default Philon RandomEngine that points to PHILOX_4X32_10",null,null],[17,"THREEFRY","","Default Threefry RandomEngine that points to…",null,null],[17,"MERSENNE","","Default Mersenne RandomEngine that points to…",null,null],[17,"DEFAULT_RANDOM_ENGINE","","Default RandomEngine that defaults to PHILOX",null,null],[8,"Convertable","","Type Trait to convert to an Array",null,null],[16,"OutType","","This type alias always points to `Self` which is the type…",39,null],[10,"convert","","Get an Array of implementors type",39,[[],["array",3]]],[8,"ConstGenerator","","Type Trait to generate a constant Array of given size",null,null],[16,"OutType","","The type of Array object returned by generate function",40,null],[10,"generate","","Create an Array of `dims` size from scalar value `self`.",40,[[["dim4",3]],["array",3]]],[8,"Indexable","","Trait bound indicating indexability",null,null],[10,"set","","Set indexing object for a given dimension",41,[[["indexer",3],["option",4]]]],[8,"HasAfEnum","","Types of the data that can be generated using ArrayFire…",null,null],[16,"InType","","This type alias points to `Self` always.",42,null],[16,"BaseType","","This type alias points to the data type used to hold real…",42,null],[16,"AbsOutType","","This type alias points to `f32` for all 32 bit size types…",42,null],[16,"ArgOutType","","This type alias points to `f64`/`f32` for floating point…",42,null],[16,"UnaryOutType","","This type alias is used to define the output Array type…",42,null],[16,"ComplexOutType","","This type alias points to complex type created from a…",42,null],[16,"MeanOutType","","This type alias points to a data type that can store the…",42,null],[16,"AggregateOutType","","This type alias points to a data type that can store the…",42,null],[16,"ProductOutType","","This type is different for b8 input type",42,null],[16,"SobelOutType","","This type alias points to the output type for given input…",42,null],[10,"get_af_dtype","","Return trait implmentors corresponding DType",42,[[],["dtype",4]]],[8,"ImplicitPromote","","This is an internal trait defined and implemented by…",null,null],[16,"Output","","This type alias points to the type of the result obtained…",43,null],[8,"FloatingPoint","","Trait qualifier to accept either real or complex typed data",null,null],[11,"is_real","","Use to check if trait implementor is real number",44,[[]]],[11,"is_complex","","Use to check if trait implementor is complex number",44,[[]]],[8,"RealFloating","","Trait qualifier to accept real data(numbers)",null,null],[8,"ComplexFloating","","Trait qualifier to accept complex data(numbers)",null,null],[8,"RealNumber","","Trait qualifier indicating it can hold real numbers only",null,null],[8,"Scanable","","Trait qualifier for the type of Arrays accepted by scan…",null,null],[8,"ImageNativeType","","Trait qualifier for type of Array\'s that are accepted by…",null,null],[8,"ImageFilterType","","Trait qualifier for type of Array\'s that are accepted by…",null,null],[8,"GrayRGBConvertible","","Trait qualifier for given type indicating conversion…",null,null],[8,"MomentsComputable","","Trait qualifier for given type indicating computability of…",null,null],[8,"MedianComputable","","Trait qualifier for given type indicating computability of…",null,null],[8,"EdgeComputable","","Trait qualifier for given type indicating if edge…",null,null],[8,"CovarianceComputable","","Trait qualifier for given type indicating computability of…",null,null],[8,"ConfidenceCCInput","","Trait qualifier for confidence connected components input",null,null],[8,"DeconvInput","","Trait qualifier for confidence connected components input",null,null],[8,"ReduceByKeyInput","","Trait qualifier for Reduction Key type",null,null],[8,"Fromf64","","Trait to convert reduction\'s scalar output to appropriate…",null,null],[10,"fromf64","","Convert to target type from a double precision value",45,[[]]],[8,"IndexableType","","Trait qualifier for the type of Arrays accepted by scan…",null,null],[8,"IntegralType","","Trait qualifier for given type indicating computability of…",null,null],[14,"mem_info","","Macro to print the current stats of ArrayFire\'s memory…",null,null],[14,"join_many","","Join multiple Arrays along a given dimension",null,null],[14,"af_print","","Print given message before printing out the Array to…",null,null],[14,"dim4","","Create a dim4 object from provided dimensions",null,null],[14,"seq","","Create a sequence object",null,null],[14,"view","","Indexing into an existing Array",null,null],[14,"eval","","Macro to evaluate individual Arrays or assignment operations",null,null],[14,"constant","","Create an array of given shape filled with a single value…",null,null],[14,"randu","","Create an array of given shape sampled from uniform…",null,null],[14,"randn","","Create an array of given shape sampled from normal…",null,null],[11,"from","","",30,[[]]],[11,"into","","",30,[[]]],[11,"to_owned","","",30,[[]]],[11,"clone_into","","",30,[[]]],[11,"borrow","","",30,[[]]],[11,"borrow_mut","","",30,[[]]],[11,"try_from","","",30,[[],["result",4]]],[11,"try_into","","",30,[[],["result",4]]],[11,"type_id","","",30,[[],["typeid",3]]],[11,"from","","",31,[[]]],[11,"into","","",31,[[]]],[11,"to_owned","","",31,[[]]],[11,"clone_into","","",31,[[]]],[11,"to_string","","",31,[[],["string",3]]],[11,"borrow","","",31,[[]]],[11,"borrow_mut","","",31,[[]]],[11,"try_from","","",31,[[],["result",4]]],[11,"try_into","","",31,[[],["result",4]]],[11,"type_id","","",31,[[],["typeid",3]]],[11,"from","","",32,[[]]],[11,"into","","",32,[[]]],[11,"borrow","","",32,[[]]],[11,"borrow_mut","","",32,[[]]],[11,"try_from","","",32,[[],["result",4]]],[11,"try_into","","",32,[[],["result",4]]],[11,"type_id","","",32,[[],["typeid",3]]],[11,"from","","",33,[[]]],[11,"into","","",33,[[]]],[11,"borrow","","",33,[[]]],[11,"borrow_mut","","",33,[[]]],[11,"try_from","","",33,[[],["result",4]]],[11,"try_into","","",33,[[],["result",4]]],[11,"type_id","","",33,[[],["typeid",3]]],[11,"from","","",34,[[]]],[11,"into","","",34,[[]]],[11,"borrow","","",34,[[]]],[11,"borrow_mut","","",34,[[]]],[11,"try_from","","",34,[[],["result",4]]],[11,"try_into","","",34,[[],["result",4]]],[11,"type_id","","",34,[[],["typeid",3]]],[11,"from","","",35,[[]]],[11,"into","","",35,[[]]],[11,"to_owned","","",35,[[]]],[11,"clone_into","","",35,[[]]],[11,"borrow","","",35,[[]]],[11,"borrow_mut","","",35,[[]]],[11,"try_from","","",35,[[],["result",4]]],[11,"try_into","","",35,[[],["result",4]]],[11,"type_id","","",35,[[],["typeid",3]]],[11,"from","","",36,[[]]],[11,"into","","",36,[[]]],[11,"to_owned","","",36,[[]]],[11,"clone_into","","",36,[[]]],[11,"to_string","","",36,[[],["string",3]]],[11,"borrow","","",36,[[]]],[11,"borrow_mut","","",36,[[]]],[11,"try_from","","",36,[[],["result",4]]],[11,"try_into","","",36,[[],["result",4]]],[11,"type_id","","",36,[[],["typeid",3]]],[11,"from","","",37,[[]]],[11,"into","","",37,[[]]],[11,"to_owned","","",37,[[]]],[11,"clone_into","","",37,[[]]],[11,"borrow","","",37,[[]]],[11,"borrow_mut","","",37,[[]]],[11,"try_from","","",37,[[],["result",4]]],[11,"try_into","","",37,[[],["result",4]]],[11,"type_id","","",37,[[],["typeid",3]]],[11,"from","","",38,[[]]],[11,"into","","",38,[[]]],[11,"to_owned","","",38,[[]]],[11,"clone_into","","",38,[[]]],[11,"borrow","","",38,[[]]],[11,"borrow_mut","","",38,[[]]],[11,"try_from","","",38,[[],["result",4]]],[11,"try_into","","",38,[[],["result",4]]],[11,"type_id","","",38,[[],["typeid",3]]],[11,"from","","",0,[[]]],[11,"into","","",0,[[]]],[11,"to_owned","","",0,[[]]],[11,"clone_into","","",0,[[]]],[11,"to_string","","",0,[[],["string",3]]],[11,"borrow","","",0,[[]]],[11,"borrow_mut","","",0,[[]]],[11,"try_from","","",0,[[],["result",4]]],[11,"try_into","","",0,[[],["result",4]]],[11,"type_id","","",0,[[],["typeid",3]]],[11,"from","","",1,[[]]],[11,"into","","",1,[[]]],[11,"to_owned","","",1,[[]]],[11,"clone_into","","",1,[[]]],[11,"to_string","","",1,[[],["string",3]]],[11,"borrow","","",1,[[]]],[11,"borrow_mut","","",1,[[]]],[11,"try_from","","",1,[[],["result",4]]],[11,"try_into","","",1,[[],["result",4]]],[11,"type_id","","",1,[[],["typeid",3]]],[11,"from","","",2,[[]]],[11,"into","","",2,[[]]],[11,"to_owned","","",2,[[]]],[11,"clone_into","","",2,[[]]],[11,"borrow","","",2,[[]]],[11,"borrow_mut","","",2,[[]]],[11,"try_from","","",2,[[],["result",4]]],[11,"try_into","","",2,[[],["result",4]]],[11,"type_id","","",2,[[],["typeid",3]]],[11,"from","","",3,[[]]],[11,"into","","",3,[[]]],[11,"to_owned","","",3,[[]]],[11,"clone_into","","",3,[[]]],[11,"borrow","","",3,[[]]],[11,"borrow_mut","","",3,[[]]],[11,"try_from","","",3,[[],["result",4]]],[11,"try_into","","",3,[[],["result",4]]],[11,"type_id","","",3,[[],["typeid",3]]],[11,"from","","",4,[[]]],[11,"into","","",4,[[]]],[11,"to_owned","","",4,[[]]],[11,"clone_into","","",4,[[]]],[11,"borrow","","",4,[[]]],[11,"borrow_mut","","",4,[[]]],[11,"try_from","","",4,[[],["result",4]]],[11,"try_into","","",4,[[],["result",4]]],[11,"type_id","","",4,[[],["typeid",3]]],[11,"from","","",5,[[]]],[11,"into","","",5,[[]]],[11,"to_owned","","",5,[[]]],[11,"clone_into","","",5,[[]]],[11,"borrow","","",5,[[]]],[11,"borrow_mut","","",5,[[]]],[11,"try_from","","",5,[[],["result",4]]],[11,"try_into","","",5,[[],["result",4]]],[11,"type_id","","",5,[[],["typeid",3]]],[11,"from","","",6,[[]]],[11,"into","","",6,[[]]],[11,"to_owned","","",6,[[]]],[11,"clone_into","","",6,[[]]],[11,"borrow","","",6,[[]]],[11,"borrow_mut","","",6,[[]]],[11,"try_from","","",6,[[],["result",4]]],[11,"try_into","","",6,[[],["result",4]]],[11,"type_id","","",6,[[],["typeid",3]]],[11,"from","","",7,[[]]],[11,"into","","",7,[[]]],[11,"to_owned","","",7,[[]]],[11,"clone_into","","",7,[[]]],[11,"borrow","","",7,[[]]],[11,"borrow_mut","","",7,[[]]],[11,"try_from","","",7,[[],["result",4]]],[11,"try_into","","",7,[[],["result",4]]],[11,"type_id","","",7,[[],["typeid",3]]],[11,"from","","",8,[[]]],[11,"into","","",8,[[]]],[11,"to_owned","","",8,[[]]],[11,"clone_into","","",8,[[]]],[11,"borrow","","",8,[[]]],[11,"borrow_mut","","",8,[[]]],[11,"try_from","","",8,[[],["result",4]]],[11,"try_into","","",8,[[],["result",4]]],[11,"type_id","","",8,[[],["typeid",3]]],[11,"from","","",9,[[]]],[11,"into","","",9,[[]]],[11,"to_owned","","",9,[[]]],[11,"clone_into","","",9,[[]]],[11,"borrow","","",9,[[]]],[11,"borrow_mut","","",9,[[]]],[11,"try_from","","",9,[[],["result",4]]],[11,"try_into","","",9,[[],["result",4]]],[11,"type_id","","",9,[[],["typeid",3]]],[11,"from","","",10,[[]]],[11,"into","","",10,[[]]],[11,"to_owned","","",10,[[]]],[11,"clone_into","","",10,[[]]],[11,"borrow","","",10,[[]]],[11,"borrow_mut","","",10,[[]]],[11,"try_from","","",10,[[],["result",4]]],[11,"try_into","","",10,[[],["result",4]]],[11,"type_id","","",10,[[],["typeid",3]]],[11,"from","","",11,[[]]],[11,"into","","",11,[[]]],[11,"to_owned","","",11,[[]]],[11,"clone_into","","",11,[[]]],[11,"borrow","","",11,[[]]],[11,"borrow_mut","","",11,[[]]],[11,"try_from","","",11,[[],["result",4]]],[11,"try_into","","",11,[[],["result",4]]],[11,"type_id","","",11,[[],["typeid",3]]],[11,"from","","",12,[[]]],[11,"into","","",12,[[]]],[11,"to_owned","","",12,[[]]],[11,"clone_into","","",12,[[]]],[11,"borrow","","",12,[[]]],[11,"borrow_mut","","",12,[[]]],[11,"try_from","","",12,[[],["result",4]]],[11,"try_into","","",12,[[],["result",4]]],[11,"type_id","","",12,[[],["typeid",3]]],[11,"from","","",13,[[]]],[11,"into","","",13,[[]]],[11,"to_owned","","",13,[[]]],[11,"clone_into","","",13,[[]]],[11,"borrow","","",13,[[]]],[11,"borrow_mut","","",13,[[]]],[11,"try_from","","",13,[[],["result",4]]],[11,"try_into","","",13,[[],["result",4]]],[11,"type_id","","",13,[[],["typeid",3]]],[11,"from","","",14,[[]]],[11,"into","","",14,[[]]],[11,"to_owned","","",14,[[]]],[11,"clone_into","","",14,[[]]],[11,"borrow","","",14,[[]]],[11,"borrow_mut","","",14,[[]]],[11,"try_from","","",14,[[],["result",4]]],[11,"try_into","","",14,[[],["result",4]]],[11,"type_id","","",14,[[],["typeid",3]]],[11,"from","","",15,[[]]],[11,"into","","",15,[[]]],[11,"to_owned","","",15,[[]]],[11,"clone_into","","",15,[[]]],[11,"borrow","","",15,[[]]],[11,"borrow_mut","","",15,[[]]],[11,"try_from","","",15,[[],["result",4]]],[11,"try_into","","",15,[[],["result",4]]],[11,"type_id","","",15,[[],["typeid",3]]],[11,"from","","",16,[[]]],[11,"into","","",16,[[]]],[11,"to_owned","","",16,[[]]],[11,"clone_into","","",16,[[]]],[11,"borrow","","",16,[[]]],[11,"borrow_mut","","",16,[[]]],[11,"try_from","","",16,[[],["result",4]]],[11,"try_into","","",16,[[],["result",4]]],[11,"type_id","","",16,[[],["typeid",3]]],[11,"from","","",17,[[]]],[11,"into","","",17,[[]]],[11,"to_owned","","",17,[[]]],[11,"clone_into","","",17,[[]]],[11,"borrow","","",17,[[]]],[11,"borrow_mut","","",17,[[]]],[11,"try_from","","",17,[[],["result",4]]],[11,"try_into","","",17,[[],["result",4]]],[11,"type_id","","",17,[[],["typeid",3]]],[11,"from","","",18,[[]]],[11,"into","","",18,[[]]],[11,"to_owned","","",18,[[]]],[11,"clone_into","","",18,[[]]],[11,"borrow","","",18,[[]]],[11,"borrow_mut","","",18,[[]]],[11,"try_from","","",18,[[],["result",4]]],[11,"try_into","","",18,[[],["result",4]]],[11,"type_id","","",18,[[],["typeid",3]]],[11,"from","","",19,[[]]],[11,"into","","",19,[[]]],[11,"to_owned","","",19,[[]]],[11,"clone_into","","",19,[[]]],[11,"borrow","","",19,[[]]],[11,"borrow_mut","","",19,[[]]],[11,"try_from","","",19,[[],["result",4]]],[11,"try_into","","",19,[[],["result",4]]],[11,"type_id","","",19,[[],["typeid",3]]],[11,"from","","",20,[[]]],[11,"into","","",20,[[]]],[11,"to_owned","","",20,[[]]],[11,"clone_into","","",20,[[]]],[11,"borrow","","",20,[[]]],[11,"borrow_mut","","",20,[[]]],[11,"try_from","","",20,[[],["result",4]]],[11,"try_into","","",20,[[],["result",4]]],[11,"type_id","","",20,[[],["typeid",3]]],[11,"from","","",21,[[]]],[11,"into","","",21,[[]]],[11,"to_owned","","",21,[[]]],[11,"clone_into","","",21,[[]]],[11,"borrow","","",21,[[]]],[11,"borrow_mut","","",21,[[]]],[11,"try_from","","",21,[[],["result",4]]],[11,"try_into","","",21,[[],["result",4]]],[11,"type_id","","",21,[[],["typeid",3]]],[11,"from","","",22,[[]]],[11,"into","","",22,[[]]],[11,"to_owned","","",22,[[]]],[11,"clone_into","","",22,[[]]],[11,"borrow","","",22,[[]]],[11,"borrow_mut","","",22,[[]]],[11,"try_from","","",22,[[],["result",4]]],[11,"try_into","","",22,[[],["result",4]]],[11,"type_id","","",22,[[],["typeid",3]]],[11,"from","","",23,[[]]],[11,"into","","",23,[[]]],[11,"to_owned","","",23,[[]]],[11,"clone_into","","",23,[[]]],[11,"borrow","","",23,[[]]],[11,"borrow_mut","","",23,[[]]],[11,"try_from","","",23,[[],["result",4]]],[11,"try_into","","",23,[[],["result",4]]],[11,"type_id","","",23,[[],["typeid",3]]],[11,"from","","",24,[[]]],[11,"into","","",24,[[]]],[11,"to_owned","","",24,[[]]],[11,"clone_into","","",24,[[]]],[11,"borrow","","",24,[[]]],[11,"borrow_mut","","",24,[[]]],[11,"try_from","","",24,[[],["result",4]]],[11,"try_into","","",24,[[],["result",4]]],[11,"type_id","","",24,[[],["typeid",3]]],[11,"from","","",25,[[]]],[11,"into","","",25,[[]]],[11,"to_owned","","",25,[[]]],[11,"clone_into","","",25,[[]]],[11,"borrow","","",25,[[]]],[11,"borrow_mut","","",25,[[]]],[11,"try_from","","",25,[[],["result",4]]],[11,"try_into","","",25,[[],["result",4]]],[11,"type_id","","",25,[[],["typeid",3]]],[11,"from","","",26,[[]]],[11,"into","","",26,[[]]],[11,"to_owned","","",26,[[]]],[11,"clone_into","","",26,[[]]],[11,"borrow","","",26,[[]]],[11,"borrow_mut","","",26,[[]]],[11,"try_from","","",26,[[],["result",4]]],[11,"try_into","","",26,[[],["result",4]]],[11,"type_id","","",26,[[],["typeid",3]]],[11,"from","","",27,[[]]],[11,"into","","",27,[[]]],[11,"to_owned","","",27,[[]]],[11,"clone_into","","",27,[[]]],[11,"borrow","","",27,[[]]],[11,"borrow_mut","","",27,[[]]],[11,"try_from","","",27,[[],["result",4]]],[11,"try_into","","",27,[[],["result",4]]],[11,"type_id","","",27,[[],["typeid",3]]],[11,"from","","",28,[[]]],[11,"into","","",28,[[]]],[11,"to_owned","","",28,[[]]],[11,"clone_into","","",28,[[]]],[11,"borrow","","",28,[[]]],[11,"borrow_mut","","",28,[[]]],[11,"try_from","","",28,[[],["result",4]]],[11,"try_into","","",28,[[],["result",4]]],[11,"type_id","","",28,[[],["typeid",3]]],[11,"from","","",29,[[]]],[11,"into","","",29,[[]]],[11,"to_owned","","",29,[[]]],[11,"clone_into","","",29,[[]]],[11,"borrow","","",29,[[]]],[11,"borrow_mut","","",29,[[]]],[11,"try_from","","",29,[[],["result",4]]],[11,"try_into","","",29,[[],["result",4]]],[11,"type_id","","",29,[[],["typeid",3]]],[11,"convert","","",30,[[],["array",3]]],[11,"generate","","",46,[[["dim4",3]],["array",3]]],[11,"generate","","",47,[[["dim4",3]],["array",3]]],[11,"set","","",30,[[["indexer",3],["option",4]]]],[11,"set","","",36,[[["indexer",3],["option",4]]]],[11,"drop","","",30,[[]]],[11,"drop","","",33,[[]]],[11,"drop","","",34,[[]]],[11,"drop","","",35,[[]]],[11,"drop","","",37,[[]]],[11,"drop","","",38,[[]]],[11,"from","","",35,[[["af_random_engine",6]]]],[11,"from","","",0,[[]]],[11,"from","","",2,[[]]],[11,"from","","",3,[[]]],[11,"from","","",6,[[]]],[11,"from","","",7,[[]]],[11,"from","","",8,[[]]],[11,"from","","",12,[[]]],[11,"from","","",17,[[]]],[11,"from","","",18,[[]]],[11,"from","","",19,[[]]],[11,"from","","",10,[[]]],[11,"into","","",48,[[],["array",3]]],[11,"clone","","",30,[[]]],[11,"clone","","",0,[[],["aferror",4]]],[11,"clone","","",1,[[],["backend",4]]],[11,"clone","","",2,[[],["dtype",4]]],[11,"clone","","",3,[[],["interptype",4]]],[11,"clone","","",4,[[],["bordertype",4]]],[11,"clone","","",5,[[],["connectivity",4]]],[11,"clone","","",6,[[],["convmode",4]]],[11,"clone","","",7,[[],["convdomain",4]]],[11,"clone","","",8,[[],["matchtype",4]]],[11,"clone","","",9,[[],["colorspace",4]]],[11,"clone","","",10,[[],["matprop",4]]],[11,"clone","","",11,[[],["normtype",4]]],[11,"clone","","",12,[[],["colormap",4]]],[11,"clone","","",13,[[],["yccstd",4]]],[11,"clone","","",14,[[],["homographytype",4]]],[11,"clone","","",15,[[],["markertype",4]]],[11,"clone","","",16,[[],["momenttype",4]]],[11,"clone","","",17,[[],["sparseformat",4]]],[11,"clone","","",18,[[],["binaryop",4]]],[11,"clone","","",19,[[],["randomenginetype",4]]],[11,"clone","","",20,[[],["scalar",4]]],[11,"clone","","",21,[[],["cannythresholdtype",4]]],[11,"clone","","",22,[[],["diffusioneq",4]]],[11,"clone","","",23,[[],["fluxfn",4]]],[11,"clone","","",24,[[],["topkfn",4]]],[11,"clone","","",25,[[],["iterativedeconvalgo",4]]],[11,"clone","","",26,[[],["inversedeconvalgo",4]]],[11,"clone","","",27,[[],["convgradienttype",4]]],[11,"clone","","",28,[[],["variancebias",4]]],[11,"clone","","",29,[[],["cublasmathmode",4]]],[11,"clone","","",31,[[],["dim4",3]]],[11,"clone","","",35,[[]]],[11,"clone","","",36,[[],["seq",3]]],[11,"clone","","",37,[[],["window",3]]],[11,"clone","","",38,[[]]],[11,"default","","",31,[[]]],[11,"default","","",33,[[]]],[11,"default","","",34,[[]]],[11,"default","","",36,[[]]],[11,"eq","","",0,[[["aferror",4]]]],[11,"eq","","",1,[[["backend",4]]]],[11,"eq","","",2,[[["dtype",4]]]],[11,"eq","","",3,[[["interptype",4]]]],[11,"eq","","",4,[[["bordertype",4]]]],[11,"eq","","",5,[[["connectivity",4]]]],[11,"eq","","",6,[[["convmode",4]]]],[11,"eq","","",7,[[["convdomain",4]]]],[11,"eq","","",8,[[["matchtype",4]]]],[11,"eq","","",9,[[["colorspace",4]]]],[11,"eq","","",10,[[["matprop",4]]]],[11,"eq","","",11,[[["normtype",4]]]],[11,"eq","","",12,[[["colormap",4]]]],[11,"eq","","",13,[[["yccstd",4]]]],[11,"eq","","",14,[[["homographytype",4]]]],[11,"eq","","",15,[[["markertype",4]]]],[11,"eq","","",16,[[["momenttype",4]]]],[11,"eq","","",17,[[["sparseformat",4]]]],[11,"eq","","",18,[[["binaryop",4]]]],[11,"eq","","",19,[[["randomenginetype",4]]]],[11,"eq","","",20,[[["scalar",4]]]],[11,"ne","","",20,[[["scalar",4]]]],[11,"eq","","",21,[[["cannythresholdtype",4]]]],[11,"eq","","",22,[[["diffusioneq",4]]]],[11,"eq","","",23,[[["fluxfn",4]]]],[11,"eq","","",24,[[["topkfn",4]]]],[11,"eq","","",25,[[["iterativedeconvalgo",4]]]],[11,"eq","","",26,[[["inversedeconvalgo",4]]]],[11,"eq","","",27,[[["convgradienttype",4]]]],[11,"eq","","",28,[[["variancebias",4]]]],[11,"eq","","",29,[[["cublasmathmode",4]]]],[11,"eq","","",31,[[["dim4",3]]]],[11,"ne","","",31,[[["dim4",3]]]],[11,"eq","","",36,[[["seq",3]]]],[11,"ne","","",36,[[["seq",3]]]],[11,"fmt","","",0,[[["formatter",3]],["result",6]]],[11,"fmt","","",1,[[["formatter",3]],["result",6]]],[11,"fmt","","",2,[[["formatter",3]],["result",6]]],[11,"fmt","","",3,[[["formatter",3]],["result",6]]],[11,"fmt","","",4,[[["formatter",3]],["result",6]]],[11,"fmt","","",5,[[["formatter",3]],["result",6]]],[11,"fmt","","",6,[[["formatter",3]],["result",6]]],[11,"fmt","","",7,[[["formatter",3]],["result",6]]],[11,"fmt","","",8,[[["formatter",3]],["result",6]]],[11,"fmt","","",9,[[["formatter",3]],["result",6]]],[11,"fmt","","",10,[[["formatter",3]],["result",6]]],[11,"fmt","","",11,[[["formatter",3]],["result",6]]],[11,"fmt","","",12,[[["formatter",3]],["result",6]]],[11,"fmt","","",13,[[["formatter",3]],["result",6]]],[11,"fmt","","",14,[[["formatter",3]],["result",6]]],[11,"fmt","","",15,[[["formatter",3]],["result",6]]],[11,"fmt","","",16,[[["formatter",3]],["result",6]]],[11,"fmt","","",17,[[["formatter",3]],["result",6]]],[11,"fmt","","",18,[[["formatter",3]],["result",6]]],[11,"fmt","","",19,[[["formatter",3]],["result",6]]],[11,"fmt","","",20,[[["formatter",3]],["result",6]]],[11,"fmt","","",21,[[["formatter",3]],["result",6]]],[11,"fmt","","",22,[[["formatter",3]],["result",6]]],[11,"fmt","","",23,[[["formatter",3]],["result",6]]],[11,"fmt","","",24,[[["formatter",3]],["result",6]]],[11,"fmt","","",25,[[["formatter",3]],["result",6]]],[11,"fmt","","",26,[[["formatter",3]],["result",6]]],[11,"fmt","","",27,[[["formatter",3]],["result",6]]],[11,"fmt","","",28,[[["formatter",3]],["result",6]]],[11,"fmt","","",29,[[["formatter",3]],["result",6]]],[11,"fmt","","",31,[[["formatter",3]],["result",6]]],[11,"fmt","","",36,[[["formatter",3]],["result",6]]],[11,"fmt","","",1,[[["formatter",3]],[["result",4],["fmterror",3]]]],[11,"fmt","","",0,[[["formatter",3]],[["result",4],["fmterror",3]]]],[11,"fmt","","",31,[[["formatter",3]],["result",6]]],[11,"fmt","","",36,[[["formatter",3]],["result",6]]],[11,"div","","",30,[[]]],[11,"div","","",30,[[["array",3]]]],[11,"div","","",30,[[["array",3]]]],[11,"rem","","",30,[[["array",3]]]],[11,"rem","","",30,[[["array",3]]]],[11,"sub","","",30,[[]]],[11,"sub","","",30,[[["array",3]]]],[11,"sub","","",30,[[["array",3]]]],[11,"add","","",30,[[]]],[11,"add","","",30,[[["array",3]]]],[11,"add","","",30,[[["array",3]]]],[11,"mul","","",30,[[]]],[11,"mul","","",30,[[["array",3]]]],[11,"mul","","",30,[[["array",3]]]],[11,"neg","","",30,[[]]],[11,"add_assign","","",30,[[["array",3]]]],[11,"sub_assign","","",30,[[["array",3]]]],[11,"mul_assign","","",30,[[["array",3]]]],[11,"div_assign","","",30,[[["array",3]]]],[11,"rem_assign","","",30,[[["array",3]]]],[11,"bitand","","",30,[[["array",3]]]],[11,"bitand","","",30,[[["array",3]]]],[11,"bitor","","",30,[[["array",3]]]],[11,"bitor","","",30,[[["array",3]]]],[11,"bitor","","",10,[[]]],[11,"bitxor","","",30,[[["array",3]]]],[11,"bitxor","","",30,[[["array",3]]]],[11,"shl","","",30,[[["array",3]]]],[11,"shl","","",30,[[["array",3]]]],[11,"shl","","",30,[[]]],[11,"shl","","",30,[[]]],[11,"shl","","",30,[[]]],[11,"shl","","",30,[[]]],[11,"shr","","",30,[[["array",3]]]],[11,"shr","","",30,[[["array",3]]]],[11,"shr","","",30,[[]]],[11,"shr","","",30,[[]]],[11,"shr","","",30,[[]]],[11,"shr","","",30,[[]]],[11,"bitand_assign","","",30,[[["array",3]]]],[11,"bitor_assign","","",30,[[["array",3]]]],[11,"bitxor_assign","","",30,[[["array",3]]]],[11,"shl_assign","","",30,[[["array",3]]]],[11,"shl_assign","","",30,[[]]],[11,"shl_assign","","",30,[[]]],[11,"shl_assign","","",30,[[]]],[11,"shl_assign","","",30,[[]]],[11,"shr_assign","","",30,[[["array",3]]]],[11,"shr_assign","","",30,[[]]],[11,"shr_assign","","",30,[[]]],[11,"shr_assign","","",30,[[]]],[11,"shr_assign","","",30,[[]]],[11,"index","","",31,[[]]],[11,"index_mut","","",31,[[]]],[11,"is_real","","Use to check if trait implementor is real number",44,[[]]],[11,"is_complex","","Use to check if trait implementor is complex number",44,[[]]]],"p":[[4,"AfError"],[4,"Backend"],[4,"DType"],[4,"InterpType"],[4,"BorderType"],[4,"Connectivity"],[4,"ConvMode"],[4,"ConvDomain"],[4,"MatchType"],[4,"ColorSpace"],[4,"MatProp"],[4,"NormType"],[4,"ColorMap"],[4,"YCCStd"],[4,"HomographyType"],[4,"MarkerType"],[4,"MomentType"],[4,"SparseFormat"],[4,"BinaryOp"],[4,"RandomEngineType"],[4,"Scalar"],[4,"CannyThresholdType"],[4,"DiffusionEq"],[4,"FluxFn"],[4,"TopkFn"],[4,"IterativeDeconvAlgo"],[4,"InverseDeconvAlgo"],[4,"ConvGradientType"],[4,"VarianceBias"],[4,"CublasMathMode"],[3,"Array"],[3,"Dim4"],[3,"Callback"],[3,"Event"],[3,"Indexer"],[3,"RandomEngine"],[3,"Seq"],[3,"Window"],[3,"Features"],[8,"Convertable"],[8,"ConstGenerator"],[8,"Indexable"],[8,"HasAfEnum"],[8,"ImplicitPromote"],[8,"FloatingPoint"],[8,"Fromf64"],[6,"c32"],[6,"c64"],[6,"af_array"]]}\ +}'); +addSearchOptions(searchIndex);initSearch(searchIndex); \ No newline at end of file diff --git a/settings.css b/settings.css new file mode 100644 index 000000000..670986588 --- /dev/null +++ b/settings.css @@ -0,0 +1 @@ +.setting-line{padding:5px;position:relative;}.setting-line>div{display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.setting-line>.title{font-size:19px;width:100%;max-width:none;border-bottom:1px solid;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{opacity:0;position:absolute;}.select-wrapper{float:right;position:relative;height:27px;min-width:25%;}.select-wrapper select{appearance:none;-moz-appearance:none;-webkit-appearance:none;background:none;border:2px solid #ccc;padding-right:28px;width:100%;}.select-wrapper img{pointer-events:none;position:absolute;right:0;bottom:0;background:#ccc;height:100%;width:28px;padding:0px 4px;}.select-wrapper select option{color:initial;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 0 2px #0a84ff,0 0 0 6px rgba(10,132,255,0.3);}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;} \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 000000000..46c80ce9b --- /dev/null +++ b/settings.html @@ -0,0 +1,19 @@ +Rustdoc settings + + + + + +

Rustdoc settings

Theme preferences
Use system theme
Preferred dark theme
Preferred light theme
+
Auto-hide item declarations
Auto-hide structs declaration
Auto-hide enums declaration
Auto-hide unions declaration
Auto-hide traits declaration
Auto-hide macros declaration
+
Auto-hide item attributes.
Auto-hide item methods' documentation
Auto-hide trait implementation documentation
Auto-hide implementors of a trait
Directly go to item in search if there is only one result
Show line numbers on code examples
Disable keyboard shortcuts
\ No newline at end of file diff --git a/settings.js b/settings.js new file mode 100644 index 000000000..50ffabf28 --- /dev/null +++ b/settings.js @@ -0,0 +1 @@ +(function(){function changeSetting(settingName,value){updateLocalStorage("rustdoc-"+settingName,value);switch(settingName){case"preferred-dark-theme":case"preferred-light-theme":case"use-system-theme":updateSystemTheme();break}}function setEvents(){var elems={toggles:document.getElementsByClassName("slider"),selects:document.getElementsByClassName("select-wrapper")};var i;if(elems.toggles&&elems.toggles.length>0){for(i=0;i0){for(i=0;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<"}else{inner2.innerText=">";sidebarToggle.style.left="0"}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/"}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px"}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});main.insertBefore(sidebar,main.firstChild);var selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}} \ No newline at end of file diff --git a/src/af_cuda_interop/lib.rs.html b/src/af_cuda_interop/lib.rs.html new file mode 100644 index 000000000..e8ea2ef4c --- /dev/null +++ b/src/af_cuda_interop/lib.rs.html @@ -0,0 +1,139 @@ +lib.rs - source + + + + + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+
+//! af-cuda-interop package is to used only when the application intends to mix
+//! arrayfire code with raw CUDA code.
+
+use arrayfire::{handle_error_general, AfError};
+use cuda_runtime_sys::cudaStream_t;
+use libc::c_int;
+
+extern "C" {
+    fn afcu_get_native_id(native_id: *mut c_int, id: c_int) -> c_int;
+    fn afcu_set_native_id(native_id: c_int) -> c_int;
+    fn afcu_get_stream(out: *mut cudaStream_t, id: c_int) -> c_int;
+}
+
+/// Get active device's id in CUDA context
+///
+/// # Parameters
+///
+/// - `id` is the integer identifier of concerned CUDA device as per ArrayFire context
+///
+/// # Return Values
+///
+/// Integer identifier of device in CUDA context
+pub fn get_device_native_id(id: i32) -> i32 {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = afcu_get_native_id(&mut temp as *mut c_int, id);
+        handle_error_general(AfError::from(err_val));
+        temp
+    }
+}
+
+/// Set active device using CUDA context's id
+///
+/// # Parameters
+///
+/// - `id` is the identifier of GPU in CUDA context
+pub fn set_device_native_id(native_id: i32) {
+    unsafe {
+        let err_val = afcu_set_native_id(native_id);
+        handle_error_general(AfError::from(err_val));
+    }
+}
+
+/// Get CUDA stream of active CUDA device
+///
+/// # Parameters
+///
+/// - `id` is the identifier of device in ArrayFire context
+///
+/// # Return Values
+///
+/// [cudaStream_t](https://docs.rs/cuda-runtime-sys/0.3.0-alpha.1/cuda_runtime_sys/type.cudaStream_t.html) handle.
+pub fn get_stream(native_id: i32) -> cudaStream_t {
+    unsafe {
+        let mut ret_val: cudaStream_t = std::ptr::null_mut();
+        let err_val = afcu_get_stream(&mut ret_val as *mut cudaStream_t, native_id);
+        handle_error_general(AfError::from(err_val));
+        ret_val
+    }
+}
+
+
\ No newline at end of file diff --git a/src/af_opencl_interop/lib.rs.html b/src/af_opencl_interop/lib.rs.html new file mode 100644 index 000000000..769f76994 --- /dev/null +++ b/src/af_opencl_interop/lib.rs.html @@ -0,0 +1,305 @@ +lib.rs - source + + + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+
+//! af-opencl-interop package is to used only when the application intends to mix
+//! arrayfire code with raw OpenCL code.
+//!
+//! Functions from this crate return OpenCL C API opaque pointers typedefs
+//!
+//! - [cl_device_id](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_device_id.html)
+//! - [cl_context](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_context.html)
+//! - [cl_command_queue](https://docs.rs/cl-sys/0.4.2/cl_sys/type.cl_command_queue.html)
+
+use arrayfire::{handle_error_general, AfError};
+use cl_sys::{
+    cl_command_queue, cl_context, cl_device_id, CL_DEVICE_TYPE_ACCELERATOR, CL_DEVICE_TYPE_ALL,
+    CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_DEFAULT, CL_DEVICE_TYPE_GPU,
+};
+use libc::c_int;
+use std::mem;
+
+/// OpenCL Vendor Platform
+#[repr(i32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum VendorPlatform {
+    AMD = 0,
+    APPLE = 1,
+    INTEL = 2,
+    NVIDIA = 3,
+    BEIGNET = 4,
+    POCL = 5,
+    UNKNOWN = -1,
+}
+
+/// OpenCL Device Type
+#[repr(u64)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum DeviceType {
+    DEFAULT = CL_DEVICE_TYPE_DEFAULT,
+    CPU = CL_DEVICE_TYPE_CPU,
+    GPU = CL_DEVICE_TYPE_GPU,
+    ACCEL = CL_DEVICE_TYPE_ACCELERATOR,
+    ALL = CL_DEVICE_TYPE_ALL,
+}
+
+extern "C" {
+    fn afcl_get_context(ctx: *mut cl_context, retain: bool) -> c_int;
+    fn afcl_get_queue(queue: *mut cl_command_queue, retain: bool) -> c_int;
+    fn afcl_get_device_id(out: *mut cl_device_id) -> c_int;
+    fn afcl_set_device_id(id: cl_device_id) -> c_int;
+
+    fn afcl_add_device_context(
+        dev_id: cl_device_id,
+        ctx: cl_context,
+        queue: cl_command_queue,
+    ) -> c_int;
+    fn afcl_set_device_context(dev_id: cl_device_id, ctx: cl_context) -> c_int;
+    fn afcl_delete_device_context(dev_id: cl_device_id, ctx: cl_context) -> c_int;
+
+    fn afcl_get_device_type(dtype: *mut c_int) -> c_int;
+    fn afcl_get_platform(ptype: *mut c_int) -> c_int;
+}
+
+/// Get the handle to active ArrayFire OpenCL context
+pub fn get_context(retain: bool) -> cl_context {
+    unsafe {
+        let mut out: cl_context = std::ptr::null_mut();
+        let err_val = afcl_get_context(&mut out as *mut cl_context, retain);
+        handle_error_general(AfError::from(err_val));
+        out
+    }
+}
+
+/// Get the handle to active ArrayFire OpenCL command queue
+pub fn get_queue(retain: bool) -> cl_command_queue {
+    unsafe {
+        let mut out: cl_command_queue = std::ptr::null_mut();
+        let err_val = afcl_get_queue(&mut out as *mut cl_command_queue, retain);
+        handle_error_general(AfError::from(err_val));
+        out
+    }
+}
+
+/// Get the handle to active ArrayFire OpenCL device
+pub fn get_device_id() -> cl_device_id {
+    unsafe {
+        let mut out: cl_device_id = std::ptr::null_mut();
+        let err_val = afcl_get_device_id(&mut out as *mut cl_device_id);
+        handle_error_general(AfError::from(err_val));
+        out
+    }
+}
+
+/// Set the cl_device_id as the active ArrayFire OpenCL device
+pub fn set_device_id(dev_id: cl_device_id) {
+    unsafe {
+        let err_val = afcl_set_device_id(dev_id);
+        handle_error_general(AfError::from(err_val));
+    }
+}
+
+/// Push user provided device, context and queue tuple to ArrayFire device mamanger
+pub fn add_device_context(dev_id: cl_device_id, ctx: cl_context, queue: cl_command_queue) {
+    unsafe {
+        let err_val = afcl_add_device_context(dev_id, ctx, queue);
+        handle_error_general(AfError::from(err_val));
+    }
+}
+
+/// Set the device identified by device & context pair as the active device for ArrayFire
+pub fn set_device_context(dev_id: cl_device_id, ctx: cl_context) {
+    unsafe {
+        let err_val = afcl_set_device_context(dev_id, ctx);
+        handle_error_general(AfError::from(err_val));
+    }
+}
+
+/// Remove the user provided device, context pair from ArrayFire device mamanger
+pub fn delete_device_context(dev_id: cl_device_id, ctx: cl_context) {
+    unsafe {
+        let err_val = afcl_delete_device_context(dev_id, ctx);
+        handle_error_general(AfError::from(err_val));
+    }
+}
+
+///// Fetch Active ArrayFire device's type i.e. CPU/GPU/Accelerator etc.
+pub fn get_device_type() -> DeviceType {
+    unsafe {
+        let mut out: i32 = 0;
+        let err_val = afcl_get_device_type(&mut out as *mut c_int);
+        handle_error_general(AfError::from(err_val));
+        match out {
+            -1 => mem::transmute(out as u64),
+            _ => DeviceType::ALL,
+        }
+    }
+}
+
+/// Fetch Active ArrayFire device's vendor platform
+pub fn get_platform() -> VendorPlatform {
+    unsafe {
+        let mut out: i32 = 0;
+        let err_val = afcl_get_platform(&mut out as *mut c_int);
+        handle_error_general(AfError::from(err_val));
+        mem::transmute(out)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs deleted file mode 100644 index def42fbf0..000000000 --- a/src/algorithm/mod.rs +++ /dev/null @@ -1,1566 +0,0 @@ -use super::core::{ - af_array, AfError, Array, BinaryOp, Fromf64, HasAfEnum, RealNumber, ReduceByKeyInput, Scanable, - HANDLE_ERROR, -}; - -use libc::{c_double, c_int, c_uint}; - -extern "C" { - fn af_sum(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_sum_nan(out: *mut af_array, input: af_array, dim: c_int, nanval: c_double) -> c_int; - fn af_product(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_product_nan(out: *mut af_array, input: af_array, dim: c_int, val: c_double) -> c_int; - fn af_min(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_max(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_all_true(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_any_true(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_count(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_sum_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_sum_nan_all(r: *mut c_double, i: *mut c_double, input: af_array, val: c_double) -> c_int; - fn af_product_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_product_nan_all( - r: *mut c_double, - i: *mut c_double, - input: af_array, - val: c_double, - ) -> c_int; - fn af_min_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_max_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_all_true_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_any_true_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_count_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int; - fn af_imin(out: *mut af_array, idx: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_imax(out: *mut af_array, idx: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_imin_all(r: *mut c_double, i: *mut c_double, idx: *mut c_uint, input: af_array) -> c_int; - fn af_imax_all(r: *mut c_double, i: *mut c_double, idx: *mut c_uint, input: af_array) -> c_int; - fn af_accum(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_where(out: *mut af_array, input: af_array) -> c_int; - fn af_diff1(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_diff2(out: *mut af_array, input: af_array, dim: c_int) -> c_int; - fn af_sort(out: *mut af_array, input: af_array, dim: c_uint, ascend: bool) -> c_int; - fn af_sort_index( - o: *mut af_array, - i: *mut af_array, - inp: af_array, - d: c_uint, - a: bool, - ) -> c_int; - fn af_set_unique(out: *mut af_array, input: af_array, is_sorted: bool) -> c_int; - fn af_set_union(out: *mut af_array, first: af_array, second: af_array, is_unq: bool) -> c_int; - fn af_set_intersect(out: *mut af_array, one: af_array, two: af_array, is_unq: bool) -> c_int; - - fn af_sort_by_key( - out_keys: *mut af_array, - out_vals: *mut af_array, - in_keys: af_array, - in_vals: af_array, - dim: c_uint, - ascend: bool, - ) -> c_int; - - fn af_scan(out: *mut af_array, inp: af_array, dim: c_int, op: c_uint, inclusive: bool) - -> c_int; - fn af_scan_by_key( - out: *mut af_array, - key: af_array, - inp: af_array, - dim: c_int, - op: c_uint, - inclusive: bool, - ) -> c_int; - fn af_all_true_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_any_true_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_count_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_max_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_min_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_product_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_product_by_key_nan( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - nan_val: c_double, - ) -> c_int; - fn af_sum_by_key( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - ) -> c_int; - fn af_sum_by_key_nan( - keys_out: *mut af_array, - vals_out: *mut af_array, - keys: af_array, - vals: af_array, - dim: c_int, - nan_val: c_double, - ) -> c_int; - fn af_max_ragged( - val_out: *mut af_array, - idx_out: *mut af_array, - input: af_array, - ragged_len: af_array, - dim: c_int, - ) -> c_int; -} - -macro_rules! dim_reduce_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => { - #[doc=$doc_str] - pub fn $fn_name(input: &Array, dim: i32) -> Array<$out_type> - where - T: HasAfEnum, - $out_type: HasAfEnum, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_name(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -dim_reduce_func_def!( - " - Sum elements along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - Result Array after summing all elements along given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, sum}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = sum(&a, 0); - print(&b); - let c = sum(&a, 1); - print(&c); - ``` - ", - sum, - af_sum, - T::AggregateOutType -); - -dim_reduce_func_def!( - " - Compute product of elements along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - Result Array after multiplying all elements along given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, product}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = product(&a, 0); - print(&b); - let c = product(&a, 1); - print(&c); - ``` - ", - product, - af_product, - T::ProductOutType -); - -dim_reduce_func_def!( - " - Find minimum among elements of given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - Result Array after finding minimum among elements along a given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, min}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = min(&a, 0); - print(&b); - let c = min(&a, 1); - print(&c); - ``` - ", - min, - af_min, - T::InType -); - -dim_reduce_func_def!( - " - Find maximum among elements of given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - Result Array after finding maximum among elements along a given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, max}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = max(&a, 0); - print(&b); - let c = max(&a, 1); - print(&c); - ``` - ", - max, - af_max, - T::InType -); - -dim_reduce_func_def!( - " - Find if all of the values along a given dimension in the Array are true - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the predicate is evaluated - - # Return Values - - Result Array that contains the result of `AND` operation of all elements along given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, all_true}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = all_true(&a, 0); - print(&b); - let c = all_true(&a, 1); - print(&c); - ``` - ", - all_true, - af_all_true, - bool -); - -dim_reduce_func_def!( - " - Find if any of the values along a given dimension in the Array are true - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the predicate is evaluated - - # Return Values - - Result Array that contains the result of `OR` operation of all elements along given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, any_true}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = any_true(&a, 0); - print(&b); - let c = any_true(&a, 1); - print(&c); - ``` - ", - any_true, - af_any_true, - bool -); - -dim_reduce_func_def!( - " - Count number of non-zero elements along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the non-zero elements are counted - - # Return Values - - Result Array with number of non-zero elements along a given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, gt, print, randu, count}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let cnst: f32 = 0.5; - let a = gt(&randu::(dims), &cnst, false); - print(&a); - let b = count(&a, 0); - print(&b); - let c = count(&a, 1); - print(&c); - ``` - ", - count, - af_count, - u32 -); - -dim_reduce_func_def!( - " - Perform exclusive sum of elements along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the exclusive scan operation is carried out - - # Return Values - - Result Array with exclusive sums of input Array elements along a given dimension - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, accum}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = accum(&a, 0); - print(&b); - let c = accum(&a, 1); - print(&c); - ``` - ", - accum, - af_accum, - T::AggregateOutType -); - -dim_reduce_func_def!( - " - Calculate first order numerical difference along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which first order difference is calculated - - # Return Values - - Result Array with first order difference values - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, diff1}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = diff1(&a, 0); - print(&b); - let c = diff1(&a, 1); - print(&c); - ``` - ", - diff1, - af_diff1, - T::InType -); - -dim_reduce_func_def!( - " - Calculate second order numerical difference along a given dimension - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which second order difference is calculated - - # Return Values - - Result Array with second order difference values - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, diff2}; - let dims = Dim4::new(&[5, 3, 1, 1]); - let a = randu::(dims); - print(&a); - let b = diff2(&a, 0); - print(&b); - let c = diff2(&a, 1); - print(&c); - ``` - ", - diff2, - af_diff2, - T::InType -); - -/// Sum along specific dimension using user specified value instead of `NAN` values -/// -/// Sum values of the `input` Array along `dim` dimension after replacing any `NAN` values in the -/// Array with the value of the parameter `nanval`. -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `dim` is reduction dimension -/// - `nanval` is value with which all the `NAN` values of Array are replaced with -/// -/// # Return Values -/// -/// Array that is reduced along given dimension via addition operation -pub fn sum_nan(input: &Array, dim: i32, nanval: f64) -> Array -where - T: HasAfEnum, - T::AggregateOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sum_nan(&mut temp as *mut af_array, input.get(), dim, nanval) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Product of elements along specific dimension using user specified value instead of `NAN` values -/// -/// Compute product of the values of the `input` Array along `dim` dimension after replacing any `NAN` values in the Array with `nanval` value. -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `dim` is reduction dimension -/// - `nanval` is value with which all the `NAN` values of Array are replaced with -/// -/// # Return Values -/// -/// Array that is reduced along given dimension via multiplication operation -pub fn product_nan(input: &Array, dim: i32, nanval: f64) -> Array -where - T: HasAfEnum, - T::ProductOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_product_nan(&mut temp as *mut af_array, input.get(), dim, nanval) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! all_reduce_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $assoc_type:ident) => { - #[doc=$doc_str] - pub fn $fn_name( - input: &Array, - ) -> ( - <::$assoc_type as HasAfEnum>::BaseType, - <::$assoc_type as HasAfEnum>::BaseType, - ) - where - T: HasAfEnum, - ::$assoc_type: HasAfEnum, - <::$assoc_type as HasAfEnum>::BaseType: HasAfEnum + Fromf64, - { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - $ffi_name( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - ( - <::$assoc_type as HasAfEnum>::BaseType::fromf64(real), - <::$assoc_type as HasAfEnum>::BaseType::fromf64(imag), - ) - } - }; -} - -all_reduce_func_def!( - " - Sum all values of the Array - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the summation result. - - Note: For non-complex data type Arrays, second value of tuple is zero. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, sum_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", sum_all(&a)); - ``` - ", - sum_all, - af_sum_all, - AggregateOutType -); - -all_reduce_func_def!( - " - Product of all values of the Array - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the product result. - - Note: For non-complex data type Arrays, second value of tuple is zero. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, product_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - let res = product_all(&a); - println!(\"Result : {:?}\", res); - ``` - ", - product_all, - af_product_all, - ProductOutType -); - -all_reduce_func_def!( - " - Find minimum among all values of the Array - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the minimum value. - - Note: For non-complex data type Arrays, second value of tuple is zero. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, min_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", min_all(&a)); - ``` - ", - min_all, - af_min_all, - InType -); - -all_reduce_func_def!( - " - Find maximum among all values of the Array - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the maximum value. - - Note: For non-complex data type Arrays, second value of tuple is zero. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, max_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", max_all(&a)); - ``` - ", - max_all, - af_max_all, - InType -); - -macro_rules! all_reduce_func_def2 { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type:ty) => { - #[doc=$doc_str] - pub fn $fn_name(input: &Array) -> ($out_type, $out_type) - where - T: HasAfEnum, - $out_type: HasAfEnum + Fromf64, - { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - $ffi_name( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (<$out_type>::fromf64(real), <$out_type>::fromf64(imag)) - } - }; -} - -all_reduce_func_def2!( - " - Find if all values of Array are non-zero - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the result of `AND` operation on all values of Array. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, all_true_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", all_true_all(&a)); - ``` - ", - all_true_all, - af_all_true_all, - bool -); - -all_reduce_func_def2!( - " - Find if any value of Array is non-zero - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the result of `OR` operation on all values of Array. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, any_true_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", any_true_all(&a)); - ``` - ", - any_true_all, - af_any_true_all, - bool -); - -all_reduce_func_def2!( - " - Count number of non-zero values in the Array - - # Parameters - - - `input` is the input Array - - # Return Values - - A tuple containing the count of non-zero values in the Array. - - # Examples - - ```rust - use arrayfire::{Dim4, print, randu, count_all}; - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - print(&a); - println!(\"Result : {:?}\", count_all(&a)); - ``` - ", - count_all, - af_count_all, - u64 -); - -/// Sum all values using user provided value for `NAN` -/// -/// Sum all the values of the `input` Array after replacing any `NAN` values with `val`. -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `val` is the val that replaces all `NAN` values of the Array before reduction operation is -/// performed. -/// -/// # Return Values -/// -/// A tuple of summation result. -/// -/// Note: For non-complex data type Arrays, second value of tuple is zero. -pub fn sum_nan_all( - input: &Array, - val: f64, -) -> ( - <::AggregateOutType as HasAfEnum>::BaseType, - <::AggregateOutType as HasAfEnum>::BaseType, -) -where - T: HasAfEnum, - ::AggregateOutType: HasAfEnum, - <::AggregateOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64, -{ - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_sum_nan_all( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - val, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - ( - <::AggregateOutType as HasAfEnum>::BaseType::fromf64(real), - <::AggregateOutType as HasAfEnum>::BaseType::fromf64(imag), - ) -} - -/// Product of all values using user provided value for `NAN` -/// -/// Compute the product of all the values of the `input` Array after replacing any `NAN` values with `val` -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `val` is the val that replaces all `NAN` values of the Array before reduction operation is -/// performed. -/// -/// # Return Values -/// -/// A tuple of product result. -/// -/// Note: For non-complex data type Arrays, second value of tuple is zero. -pub fn product_nan_all( - input: &Array, - val: f64, -) -> ( - <::ProductOutType as HasAfEnum>::BaseType, - <::ProductOutType as HasAfEnum>::BaseType, -) -where - T: HasAfEnum, - ::ProductOutType: HasAfEnum, - <::ProductOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64, -{ - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_product_nan_all( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - val, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - ( - <::ProductOutType as HasAfEnum>::BaseType::fromf64(real), - <::ProductOutType as HasAfEnum>::BaseType::fromf64(imag), - ) -} - -macro_rules! dim_ireduce_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ident) => { - #[doc=$doc_str] - pub fn $fn_name(input: &Array, dim: i32) -> (Array, Array) - where - T: HasAfEnum, - T::$out_type: HasAfEnum, - { - let mut temp: af_array = std::ptr::null_mut(); - let mut idx: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut temp as *mut af_array, - &mut idx as *mut af_array, - input.get(), - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (temp.into(), idx.into()) - } - }; -} - -dim_ireduce_func_def!(" - Find minimum value along given dimension and their corresponding indices - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - A tuple of Arrays: Array minimum values and Array containing their index along the reduced dimension. - ", imin, af_imin, InType); - -dim_ireduce_func_def!(" - Find maximum value along given dimension and their corresponding indices - - # Parameters - - - `input` - Input Array - - `dim` - Dimension along which the input Array will be reduced - - # Return Values - - A tuple of Arrays: Array maximum values and Array containing their index along the reduced dimension. - ", imax, af_imax, InType); - -macro_rules! all_ireduce_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $assoc_type:ident) => { - #[doc=$doc_str] - pub fn $fn_name( - input: &Array, - ) -> ( - <::$assoc_type as HasAfEnum>::BaseType, - <::$assoc_type as HasAfEnum>::BaseType, - u32, - ) - where - T: HasAfEnum, - ::$assoc_type: HasAfEnum, - <::$assoc_type as HasAfEnum>::BaseType: HasAfEnum + Fromf64, - { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - let mut temp: u32 = 0; - - let err_val = unsafe { - $ffi_name( - &mut real as *mut c_double, - &mut imag as *mut c_double, - &mut temp as *mut c_uint, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - ( - <::$assoc_type as HasAfEnum>::BaseType::fromf64(real), - <::$assoc_type as HasAfEnum>::BaseType::fromf64(imag), - temp, - ) - } - }; -} - -all_ireduce_func_def!( - " - Find minimum and it's index in the whole Array - - # Parameters - - `input` - Input Array - - # Return Values - - A triplet with - - * minimum element of Array in the first component. - * second component of value zero if Array is of non-complex type. - * index of minimum element in the third component. - ", - imin_all, - af_imin_all, - InType -); -all_ireduce_func_def!( - " - Find maximum and it's index in the whole Array - - # Parameters - - `input` - Input Array - - # Return Values - - A triplet with - - - maximum element of Array in the first component. - - second component of value zero if Array is of non-complex type. - - index of maximum element in the third component. - ", - imax_all, - af_imax_all, - InType -); - -/// Locate the indices of non-zero elements. -/// -/// The locations are provided by flattening the input into a linear array. -/// -/// # Parameters -/// -/// - `input` - Input Array -/// -/// # Return Values -/// -/// Array of indices where the input Array has non-zero values. -pub fn locate(input: &Array) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_where(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Sort the values in input Arrays -/// -/// Sort an multidimensional Array along a given dimension -/// -/// # Parameters -/// -/// - `input` - Input Array -/// - `dim` - Dimension along which to sort -/// - `ascending` - Sorted output will have ascending values if -/// ```True``` and descending order otherwise. -/// -/// # Return Values -/// -/// Sorted Array. -pub fn sort(input: &Array, dim: u32, ascending: bool) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sort(&mut temp as *mut af_array, input.get(), dim, ascending) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Sort the values in input Arrays -/// -/// # Parameters -/// -/// - `input` - Input Array -/// - `dim` - Dimension along which to sort -/// - `ascending` - Sorted output will have ascending values if -/// ```True``` and descending order otherwise. -/// -/// # Return Values -/// -/// A tuple of Arrays. -/// -/// The first Array contains the keys based on sorted values. -/// -/// The second Array contains the original indices of the sorted values. -pub fn sort_index(input: &Array, dim: u32, ascending: bool) -> (Array, Array) -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let mut idx: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_sort_index( - &mut temp as *mut af_array, - &mut idx as *mut af_array, - input.get(), - dim, - ascending, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (temp.into(), idx.into()) -} - -/// Sort the values in input Arrays -/// -/// Sort an multidimensional Array based on keys -/// -/// # Parameters -/// -/// - `keys` - Array with key values -/// - `vals` - Array with input values -/// - `dim` - Dimension along which to sort -/// - `ascending` - Sorted output will have ascending values if ```True``` and descending order otherwise. -/// -/// # Return Values -/// -/// A tuple of Arrays. -/// -/// The first Array contains the keys based on sorted values. -/// -/// The second Array contains the sorted values. -pub fn sort_by_key( - keys: &Array, - vals: &Array, - dim: u32, - ascending: bool, -) -> (Array, Array) -where - K: HasAfEnum + RealNumber, - V: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let mut temp2: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_sort_by_key( - &mut temp as *mut af_array, - &mut temp2 as *mut af_array, - keys.get(), - vals.get(), - dim, - ascending, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (temp.into(), temp2.into()) -} - -/// Find unique values from a Set -/// -/// # Parameters -/// -/// - `input` - Input Array -/// - `is_sorted` - is a boolean variable. If ```True`` -/// indicates, the `input` Array is sorted. -/// -/// # Return Values -/// -/// An Array of unique values from the input Array. -pub fn set_unique(input: &Array, is_sorted: bool) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_set_unique(&mut temp as *mut af_array, input.get(), is_sorted) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find union of two sets -/// -/// # Parameters -/// -/// - `first` is one of the input sets -/// - `second` is the other of the input sets -/// - `is_unique` is a boolean value indicates if the input sets are unique -/// -/// # Return Values -/// -/// An Array with union of the input sets -pub fn set_union(first: &Array, second: &Array, is_unique: bool) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_set_union( - &mut temp as *mut af_array, - first.get(), - second.get(), - is_unique, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find intersection of two sets -/// -/// # Parameters -/// -/// - `first` is one of the input sets -/// - `second` is the other of the input sets -/// - `is_unique` is a boolean value indicates if the input sets are unique -/// -/// # Return Values -/// -/// An Array with intersection of the input sets -pub fn set_intersect(first: &Array, second: &Array, is_unique: bool) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_set_intersect( - &mut temp as *mut af_array, - first.get(), - second.get(), - is_unique, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Generalized scan -/// -/// # Parameters -/// -/// - `input` is the data on which scan is to be performed -/// - `dim` is the dimension along which scan operation is to be performed -/// - `op` takes value of [BinaryOp](./enum.BinaryOp.html) enum indicating -/// the type of scan operation -/// - `inclusive` says if inclusive/exclusive scan is to be performed -/// -/// # Return Values -/// -/// Output Array of scanned input -pub fn scan( - input: &Array, - dim: i32, - op: BinaryOp, - inclusive: bool, -) -> Array -where - T: HasAfEnum, - T::AggregateOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_scan( - &mut temp as *mut af_array, - input.get(), - dim, - op as u32, - inclusive, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Generalized scan by key -/// -/// # Parameters -/// -/// - `key` is the key Array -/// - `input` is the data on which scan is to be performed -/// - `dim` is the dimension along which scan operation is to be performed -/// - `op` takes value of [BinaryOp](./enum.BinaryOp.html) enum indicating -/// the type of scan operation -/// - `inclusive` says if inclusive/exclusive scan is to be performed -/// -/// # Return Values -/// -/// Output Array of scanned input -pub fn scan_by_key( - key: &Array, - input: &Array, - dim: i32, - op: BinaryOp, - inclusive: bool, -) -> Array -where - V: HasAfEnum, - V::AggregateOutType: HasAfEnum, - K: HasAfEnum + Scanable, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_scan_by_key( - &mut temp as *mut af_array, - key.get(), - input.get(), - dim, - op as u32, - inclusive, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! dim_reduce_by_key_func_def { - ($brief_str: expr, $ex_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => { - #[doc=$brief_str] - /// # Parameters - /// - /// - `keys` - key Array - /// - `vals` - value Array - /// - `dim` - Dimension along which the input Array is reduced - /// - /// # Return Values - /// - /// Tuple of Arrays, with output keys and values after reduction - /// - #[doc=$ex_str] - pub fn $fn_name( - keys: &Array, - vals: &Array, - dim: i32, - ) -> (Array, Array<$out_type>) - where - KeyType: ReduceByKeyInput, - ValueType: HasAfEnum, - $out_type: HasAfEnum, - { - let mut out_keys: af_array = std::ptr::null_mut(); - let mut out_vals: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut out_keys as *mut af_array, - &mut out_vals as *mut af_array, - keys.get(), - vals.get(), - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (out_keys.into(), out_vals.into()) - } - }; -} - -dim_reduce_by_key_func_def!( - " -Key based AND of elements along a given dimension - -All positive non-zero values are considered true, while negative and zero -values are considered as false. -", - " -# Examples -```rust -use arrayfire::{Dim4, print, randu, all_true_by_key}; -let dims = Dim4::new(&[5, 3, 1, 1]); -let vals = randu::(dims); -let keys = randu::(Dim4::new(&[5, 1, 1, 1])); -print(&vals); -print(&keys); -let (out_keys, out_vals) = all_true_by_key(&keys, &vals, 0); -print(&out_keys); -print(&out_vals); -``` -", - all_true_by_key, - af_all_true_by_key, - ValueType::AggregateOutType -); - -dim_reduce_by_key_func_def!( - " -Key based OR of elements along a given dimension - -All positive non-zero values are considered true, while negative and zero -values are considered as false. -", - " -# Examples -```rust -use arrayfire::{Dim4, print, randu, any_true_by_key}; -let dims = Dim4::new(&[5, 3, 1, 1]); -let vals = randu::(dims); -let keys = randu::(Dim4::new(&[5, 1, 1, 1])); -print(&vals); -print(&keys); -let (out_keys, out_vals) = any_true_by_key(&keys, &vals, 0); -print(&out_keys); -print(&out_vals); -``` -", - any_true_by_key, - af_any_true_by_key, - ValueType::AggregateOutType -); - -dim_reduce_by_key_func_def!( - "Find total count of elements with similar keys along a given dimension", - "", - count_by_key, - af_count_by_key, - ValueType::AggregateOutType -); - -dim_reduce_by_key_func_def!( - "Find maximum among values of similar keys along a given dimension", - "", - max_by_key, - af_max_by_key, - ValueType::AggregateOutType -); - -dim_reduce_by_key_func_def!( - "Find minimum among values of similar keys along a given dimension", - "", - min_by_key, - af_min_by_key, - ValueType::AggregateOutType -); - -dim_reduce_by_key_func_def!( - "Find product of all values with similar keys along a given dimension", - "", - product_by_key, - af_product_by_key, - ValueType::ProductOutType -); - -dim_reduce_by_key_func_def!( - "Find sum of all values with similar keys along a given dimension", - "", - sum_by_key, - af_sum_by_key, - ValueType::AggregateOutType -); - -macro_rules! dim_reduce_by_key_nan_func_def { - ($brief_str: expr, $ex_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => { - #[doc=$brief_str] - /// - /// This version of sum by key can replaced all NaN values in the input - /// with a user provided value before performing the reduction operation. - /// # Parameters - /// - /// - `keys` - key Array - /// - `vals` - value Array - /// - `dim` - Dimension along which the input Array is reduced - /// - /// # Return Values - /// - /// Tuple of Arrays, with output keys and values after reduction - /// - #[doc=$ex_str] - pub fn $fn_name( - keys: &Array, - vals: &Array, - dim: i32, - replace_value: f64, - ) -> (Array, Array<$out_type>) - where - KeyType: ReduceByKeyInput, - ValueType: HasAfEnum, - $out_type: HasAfEnum, - { - let mut out_keys: af_array = std::ptr::null_mut(); - let mut out_vals: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut out_keys as *mut af_array, - &mut out_vals as *mut af_array, - keys.get(), - vals.get(), - dim, - replace_value, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (out_keys.into(), out_vals.into()) - } - }; -} - -dim_reduce_by_key_nan_func_def!( - "Compute sum of all values with similar keys along a given dimension", - "", - sum_by_key_nan, - af_sum_by_key_nan, - ValueType::AggregateOutType -); - -dim_reduce_by_key_nan_func_def!( - "Compute product of all values with similar keys along a given dimension", - "", - product_by_key_nan, - af_product_by_key_nan, - ValueType::ProductOutType -); - -/// Max reduction along given axis as per ragged lengths provided -/// -/// # Parameters -/// -/// - `input` contains the input values to be reduced -/// - `ragged_len` array containing number of elements to use when reducing along `dim` -/// - `dim` is the dimension along which the max operation occurs -/// -/// # Return Values -/// -/// Tuple of Arrays: -/// - First element: An Array containing the maximum ragged values in `input` along `dim` -/// according to `ragged_len` -/// - Second Element: An Array containing the locations of the maximum ragged values in -/// `input` along `dim` according to `ragged_len` -/// -/// # Examples -/// ```rust -/// use arrayfire::{Array, dim4, print, randu, max_ragged}; -/// let vals: [f32; 6] = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0]; -/// let rlens: [u32; 2] = [9, 2]; -/// let varr = Array::new(&vals, dim4![3, 2]); -/// let rarr = Array::new(&rlens, dim4![1, 2]); -/// print(&varr); -/// // 1 4 -/// // 2 5 -/// // 3 6 -/// print(&rarr); // numbers of elements to participate in reduction along given axis -/// // 9 2 -/// let (out, idx) = max_ragged(&varr, &rarr, 0); -/// print(&out); -/// // 3 5 -/// print(&idx); -/// // 2 1 //Since 3 is max element for given length 9 along first column -/// //Since 5 is max element for given length 2 along second column -/// ``` -pub fn max_ragged( - input: &Array, - ragged_len: &Array, - dim: i32, -) -> (Array, Array) -where - T: HasAfEnum, - T::InType: HasAfEnum, -{ - let mut out_vals: af_array = std::ptr::null_mut(); - let mut out_idxs: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_max_ragged( - &mut out_vals as *mut af_array, - &mut out_idxs as *mut af_array, - input.get(), - ragged_len.get(), - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (out_vals.into(), out_idxs.into()) -} - -#[cfg(test)] -mod tests { - use super::super::core::c32; - use super::{imax_all, imin_all, product_nan_all, sum_all, sum_nan_all}; - use crate::core::set_device; - use crate::randu; - - #[test] - fn all_reduce_api() { - set_device(0); - let a = randu!(c32; 10, 10); - println!("Reduction of complex f32 matrix: {:?}", sum_all(&a)); - - let b = randu!(bool; 10, 10); - println!("reduction of bool matrix: {:?}", sum_all(&b)); - - println!( - "reduction of complex f32 matrix after replacing nan with 1.0: {:?}", - product_nan_all(&a, 1.0) - ); - - println!( - "reduction of bool matrix after replacing nan with 0.0: {:?}", - sum_nan_all(&b, 0.0) - ); - } - - #[test] - fn all_ireduce_api() { - set_device(0); - let a = randu!(c32; 10); - println!("Reduction of complex f32 matrix: {:?}", imin_all(&a)); - - let b = randu!(u32; 10); - println!("reduction of bool matrix: {:?}", imax_all(&b)); - } -} diff --git a/src/arrayfire/algorithm/mod.rs.html b/src/arrayfire/algorithm/mod.rs.html new file mode 100644 index 000000000..969d0f0d7 --- /dev/null +++ b/src/arrayfire/algorithm/mod.rs.html @@ -0,0 +1,3113 @@ +mod.rs - source + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+
+use super::core::{
+    af_array, AfError, Array, BinaryOp, Fromf64, HasAfEnum, RealNumber, ReduceByKeyInput, Scanable,
+    HANDLE_ERROR,
+};
+
+use libc::{c_double, c_int, c_uint};
+
+extern "C" {
+    fn af_sum(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_sum_nan(out: *mut af_array, input: af_array, dim: c_int, nanval: c_double) -> c_int;
+    fn af_product(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_product_nan(out: *mut af_array, input: af_array, dim: c_int, val: c_double) -> c_int;
+    fn af_min(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_max(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_all_true(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_any_true(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_count(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_sum_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_sum_nan_all(r: *mut c_double, i: *mut c_double, input: af_array, val: c_double) -> c_int;
+    fn af_product_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_product_nan_all(
+        r: *mut c_double,
+        i: *mut c_double,
+        input: af_array,
+        val: c_double,
+    ) -> c_int;
+    fn af_min_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_max_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_all_true_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_any_true_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_count_all(r: *mut c_double, i: *mut c_double, input: af_array) -> c_int;
+    fn af_imin(out: *mut af_array, idx: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_imax(out: *mut af_array, idx: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_imin_all(r: *mut c_double, i: *mut c_double, idx: *mut c_uint, input: af_array) -> c_int;
+    fn af_imax_all(r: *mut c_double, i: *mut c_double, idx: *mut c_uint, input: af_array) -> c_int;
+    fn af_accum(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_where(out: *mut af_array, input: af_array) -> c_int;
+    fn af_diff1(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_diff2(out: *mut af_array, input: af_array, dim: c_int) -> c_int;
+    fn af_sort(out: *mut af_array, input: af_array, dim: c_uint, ascend: bool) -> c_int;
+    fn af_sort_index(
+        o: *mut af_array,
+        i: *mut af_array,
+        inp: af_array,
+        d: c_uint,
+        a: bool,
+    ) -> c_int;
+    fn af_set_unique(out: *mut af_array, input: af_array, is_sorted: bool) -> c_int;
+    fn af_set_union(out: *mut af_array, first: af_array, second: af_array, is_unq: bool) -> c_int;
+    fn af_set_intersect(out: *mut af_array, one: af_array, two: af_array, is_unq: bool) -> c_int;
+
+    fn af_sort_by_key(
+        out_keys: *mut af_array,
+        out_vals: *mut af_array,
+        in_keys: af_array,
+        in_vals: af_array,
+        dim: c_uint,
+        ascend: bool,
+    ) -> c_int;
+
+    fn af_scan(out: *mut af_array, inp: af_array, dim: c_int, op: c_uint, inclusive: bool)
+        -> c_int;
+    fn af_scan_by_key(
+        out: *mut af_array,
+        key: af_array,
+        inp: af_array,
+        dim: c_int,
+        op: c_uint,
+        inclusive: bool,
+    ) -> c_int;
+    fn af_all_true_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_any_true_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_count_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_max_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_min_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_product_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_product_by_key_nan(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+        nan_val: c_double,
+    ) -> c_int;
+    fn af_sum_by_key(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+    ) -> c_int;
+    fn af_sum_by_key_nan(
+        keys_out: *mut af_array,
+        vals_out: *mut af_array,
+        keys: af_array,
+        vals: af_array,
+        dim: c_int,
+        nan_val: c_double,
+    ) -> c_int;
+    fn af_max_ragged(
+        val_out: *mut af_array,
+        idx_out: *mut af_array,
+        input: af_array,
+        ragged_len: af_array,
+        dim: c_int,
+    ) -> c_int;
+}
+
+macro_rules! dim_reduce_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>, dim: i32) -> Array<$out_type>
+        where
+            T: HasAfEnum,
+            $out_type: HasAfEnum,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(&mut temp as *mut af_array, input.get(), dim);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+dim_reduce_func_def!(
+    "
+    Sum elements along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    Result Array after summing all elements along given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, sum};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = sum(&a, 0);
+    print(&b);
+    let c = sum(&a, 1);
+    print(&c);
+    ```
+    ",
+    sum,
+    af_sum,
+    T::AggregateOutType
+);
+
+dim_reduce_func_def!(
+    "
+    Compute product of elements along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    Result Array after multiplying all elements along given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, product};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = product(&a, 0);
+    print(&b);
+    let c = product(&a, 1);
+    print(&c);
+    ```
+    ",
+    product,
+    af_product,
+    T::ProductOutType
+);
+
+dim_reduce_func_def!(
+    "
+    Find minimum among elements of given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    Result Array after finding minimum among elements along a given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, min};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = min(&a, 0);
+    print(&b);
+    let c = min(&a, 1);
+    print(&c);
+    ```
+    ",
+    min,
+    af_min,
+    T::InType
+);
+
+dim_reduce_func_def!(
+    "
+    Find maximum among elements of given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    Result Array after finding maximum among elements along a given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, max};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = max(&a, 0);
+    print(&b);
+    let c = max(&a, 1);
+    print(&c);
+    ```
+    ",
+    max,
+    af_max,
+    T::InType
+);
+
+dim_reduce_func_def!(
+    "
+    Find if all of the values along a given dimension in the Array are true
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the predicate is evaluated
+
+    # Return Values
+
+    Result Array that contains the result of `AND` operation of all elements along given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, all_true};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = all_true(&a, 0);
+    print(&b);
+    let c = all_true(&a, 1);
+    print(&c);
+    ```
+    ",
+    all_true,
+    af_all_true,
+    bool
+);
+
+dim_reduce_func_def!(
+    "
+    Find if any of the values along a given dimension in the Array are true
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the predicate is evaluated
+
+    # Return Values
+
+    Result Array that contains the result of `OR` operation of all elements along given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, any_true};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = any_true(&a, 0);
+    print(&b);
+    let c = any_true(&a, 1);
+    print(&c);
+    ```
+    ",
+    any_true,
+    af_any_true,
+    bool
+);
+
+dim_reduce_func_def!(
+    "
+    Count number of non-zero elements along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the non-zero elements are counted
+
+    # Return Values
+
+    Result Array with number of non-zero elements along a given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, gt, print, randu, count};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let cnst: f32 = 0.5;
+    let a = gt(&randu::<f32>(dims), &cnst, false);
+    print(&a);
+    let b = count(&a, 0);
+    print(&b);
+    let c = count(&a, 1);
+    print(&c);
+    ```
+    ",
+    count,
+    af_count,
+    u32
+);
+
+dim_reduce_func_def!(
+    "
+    Perform exclusive sum of elements along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which the exclusive scan operation is carried out
+
+    # Return Values
+
+    Result Array with exclusive sums of input Array elements along a given dimension
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, accum};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = accum(&a, 0);
+    print(&b);
+    let c = accum(&a, 1);
+    print(&c);
+    ```
+    ",
+    accum,
+    af_accum,
+    T::AggregateOutType
+);
+
+dim_reduce_func_def!(
+    "
+    Calculate first order numerical difference along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which first order difference is calculated
+
+    # Return Values
+
+    Result Array with first order difference values
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, diff1};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = diff1(&a, 0);
+    print(&b);
+    let c = diff1(&a, 1);
+    print(&c);
+    ```
+    ",
+    diff1,
+    af_diff1,
+    T::InType
+);
+
+dim_reduce_func_def!(
+    "
+    Calculate second order numerical difference along a given dimension
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim`   - Dimension along which second order difference is calculated
+
+    # Return Values
+
+    Result Array with second order difference values
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, diff2};
+    let dims = Dim4::new(&[5, 3, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let b = diff2(&a, 0);
+    print(&b);
+    let c = diff2(&a, 1);
+    print(&c);
+    ```
+    ",
+    diff2,
+    af_diff2,
+    T::InType
+);
+
+/// Sum along specific dimension using user specified value instead of `NAN` values
+///
+/// Sum values of the `input` Array along `dim` dimension after replacing any `NAN` values in the
+/// Array with the value of the parameter `nanval`.
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `dim` is reduction dimension
+/// - `nanval` is value with which all the `NAN` values of Array are replaced with
+///
+/// # Return Values
+///
+/// Array that is reduced along given dimension via addition operation
+pub fn sum_nan<T>(input: &Array<T>, dim: i32, nanval: f64) -> Array<T::AggregateOutType>
+where
+    T: HasAfEnum,
+    T::AggregateOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_sum_nan(&mut temp as *mut af_array, input.get(), dim, nanval);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Product of elements along specific dimension using user specified value instead of `NAN` values
+///
+/// Compute product of the values of the `input` Array along `dim` dimension after replacing any `NAN` values in the Array with `nanval` value.
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `dim` is reduction dimension
+/// - `nanval` is value with which all the `NAN` values of Array are replaced with
+///
+/// # Return Values
+///
+/// Array that is reduced along given dimension via multiplication operation
+pub fn product_nan<T>(input: &Array<T>, dim: i32, nanval: f64) -> Array<T::ProductOutType>
+where
+    T: HasAfEnum,
+    T::ProductOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_product_nan(&mut temp as *mut af_array, input.get(), dim, nanval);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! all_reduce_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $assoc_type:ident) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>)
+            -> (
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType,
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType
+               )
+        where
+            T: HasAfEnum,
+            <T as HasAfEnum>::$assoc_type: HasAfEnum,
+            <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType: HasAfEnum + Fromf64,
+        {
+            let mut real: f64 = 0.0;
+            let mut imag: f64 = 0.0;
+            unsafe {
+                let err_val = $ffi_name(
+                    &mut real as *mut c_double, &mut imag as *mut c_double, input.get(),
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            (
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType::fromf64(real),
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType::fromf64(imag),
+            )
+        }
+    };
+}
+
+all_reduce_func_def!(
+    "
+    Sum all values of the Array
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the summation result.
+
+    Note: For non-complex data type Arrays, second value of tuple is zero.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, sum_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", sum_all(&a));
+    ```
+    ",
+    sum_all,
+    af_sum_all,
+    AggregateOutType
+);
+
+all_reduce_func_def!(
+    "
+    Product of all values of the Array
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the product result.
+
+    Note: For non-complex data type Arrays, second value of tuple is zero.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, product_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    let res = product_all(&a);
+    println!(\"Result : {:?}\", res);
+    ```
+    ",
+    product_all,
+    af_product_all,
+    ProductOutType
+);
+
+all_reduce_func_def!(
+    "
+    Find minimum among all values of the Array
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the minimum value.
+
+    Note: For non-complex data type Arrays, second value of tuple is zero.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, min_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", min_all(&a));
+    ```
+    ",
+    min_all,
+    af_min_all,
+    InType
+);
+
+all_reduce_func_def!(
+    "
+    Find maximum among all values of the Array
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the maximum value.
+
+    Note: For non-complex data type Arrays, second value of tuple is zero.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, max_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", max_all(&a));
+    ```
+    ",
+    max_all,
+    af_max_all,
+    InType
+);
+
+macro_rules! all_reduce_func_def2 {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type:ty) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>) -> ($out_type, $out_type)
+        where
+            T: HasAfEnum,
+            $out_type: HasAfEnum + Fromf64
+        {
+            let mut real: f64 = 0.0;
+            let mut imag: f64 = 0.0;
+            unsafe {
+                let err_val = $ffi_name(
+                    &mut real as *mut c_double, &mut imag as *mut c_double, input.get(),
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            (<$out_type>::fromf64(real), <$out_type>::fromf64(imag))
+        }
+    };
+}
+
+all_reduce_func_def2!(
+    "
+    Find if all values of Array are non-zero
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the result of `AND` operation on all values of Array.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, all_true_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", all_true_all(&a));
+    ```
+    ",
+    all_true_all,
+    af_all_true_all,
+    bool
+);
+
+all_reduce_func_def2!(
+    "
+    Find if any value of Array is non-zero
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the result of `OR` operation on all values of Array.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, any_true_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", any_true_all(&a));
+    ```
+    ",
+    any_true_all,
+    af_any_true_all,
+    bool
+);
+
+all_reduce_func_def2!(
+    "
+    Count number of non-zero values in the Array
+
+    # Parameters
+
+    - `input` is the input Array
+
+    # Return Values
+
+    A tuple containing the count of non-zero values in the Array.
+
+    # Examples
+
+    ```rust
+    use arrayfire::{Dim4, print, randu, count_all};
+    let dims = Dim4::new(&[5, 5, 1, 1]);
+    let a = randu::<f32>(dims);
+    print(&a);
+    println!(\"Result : {:?}\", count_all(&a));
+    ```
+    ",
+    count_all,
+    af_count_all,
+    u64
+);
+
+/// Sum all values using user provided value for `NAN`
+///
+/// Sum all the values of the `input` Array after replacing any `NAN` values with `val`.
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `val` is the val that replaces all `NAN` values of the Array before reduction operation is
+/// performed.
+///
+/// # Return Values
+///
+/// A tuple of summation result.
+///
+/// Note: For non-complex data type Arrays, second value of tuple is zero.
+pub fn sum_nan_all<T>(
+    input: &Array<T>,
+    val: f64,
+) -> (
+    <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType,
+    <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType,
+)
+where
+    T: HasAfEnum,
+    <T as HasAfEnum>::AggregateOutType: HasAfEnum,
+    <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64,
+{
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_sum_nan_all(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+            val,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (
+        <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType::fromf64(real),
+        <<T as HasAfEnum>::AggregateOutType as HasAfEnum>::BaseType::fromf64(imag),
+    )
+}
+
+/// Product of all values using user provided value for `NAN`
+///
+/// Compute the product of all the values of the `input` Array after replacing any `NAN` values with `val`
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `val` is the val that replaces all `NAN` values of the Array before reduction operation is
+/// performed.
+///
+/// # Return Values
+///
+/// A tuple of product result.
+///
+/// Note: For non-complex data type Arrays, second value of tuple is zero.
+pub fn product_nan_all<T>(
+    input: &Array<T>,
+    val: f64,
+) -> (
+    <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType,
+    <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType,
+)
+where
+    T: HasAfEnum,
+    <T as HasAfEnum>::ProductOutType: HasAfEnum,
+    <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType: HasAfEnum + Fromf64,
+{
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_product_nan_all(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+            val,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (
+        <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType::fromf64(real),
+        <<T as HasAfEnum>::ProductOutType as HasAfEnum>::BaseType::fromf64(imag),
+    )
+}
+
+macro_rules! dim_ireduce_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ident) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>, dim: i32) -> (Array<T::$out_type>, Array<u32>)
+        where
+            T: HasAfEnum,
+            T::$out_type: HasAfEnum,
+        {
+            unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let mut idx: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array, &mut idx as *mut af_array, input.get(), dim,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            (temp.into(), idx.into())
+            }
+        }
+    };
+}
+
+dim_ireduce_func_def!("
+    Find minimum value along given dimension and their corresponding indices
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim` - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    A tuple of Arrays: Array minimum values and Array containing their index along the reduced dimension.
+    ", imin, af_imin, InType);
+
+dim_ireduce_func_def!("
+    Find maximum value along given dimension and their corresponding indices
+
+    # Parameters
+
+    - `input` - Input Array
+    - `dim` - Dimension along which the input Array will be reduced
+
+    # Return Values
+
+    A tuple of Arrays: Array maximum values and Array containing their index along the reduced dimension.
+    ", imax, af_imax, InType);
+
+macro_rules! all_ireduce_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident, $assoc_type:ident) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>)
+            -> (
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType,
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType,
+                u32
+               )
+        where
+            T: HasAfEnum,
+            <T as HasAfEnum>::$assoc_type: HasAfEnum,
+            <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType: HasAfEnum + Fromf64,
+        {
+            let mut real: f64 = 0.0;
+            let mut imag: f64 = 0.0;
+            let mut temp: u32 = 0;
+            unsafe {
+                let err_val = $ffi_name(
+                    &mut real as *mut c_double, &mut imag as *mut c_double,
+                    &mut temp as *mut c_uint, input.get(),
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            (
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType::fromf64(real),
+                <<T as HasAfEnum>::$assoc_type as HasAfEnum>::BaseType::fromf64(imag),
+                temp,
+            )
+        }
+    };
+}
+
+all_ireduce_func_def!(
+    "
+    Find minimum and it's index in the whole Array
+
+    # Parameters
+
+    `input` - Input Array
+
+    # Return Values
+
+    A triplet with
+
+      * minimum element of Array in the first component.
+      * second component of value zero if Array is of non-complex type.
+      * index of minimum element in the third component.
+    ",
+    imin_all,
+    af_imin_all,
+    InType
+);
+all_ireduce_func_def!(
+    "
+    Find maximum and it's index in the whole Array
+
+    # Parameters
+
+    `input` - Input Array
+
+    # Return Values
+
+    A triplet with
+
+      - maximum element of Array in the first component.
+      - second component of value zero if Array is of non-complex type.
+      - index of maximum element in the third component.
+    ",
+    imax_all,
+    af_imax_all,
+    InType
+);
+
+/// Locate the indices of non-zero elements.
+///
+/// The locations are provided by flattening the input into a linear array.
+///
+/// # Parameters
+///
+/// - `input` - Input Array
+///
+/// # Return Values
+///
+/// Array of indices where the input Array has non-zero values.
+pub fn locate<T: HasAfEnum>(input: &Array<T>) -> Array<u32> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_where(&mut temp as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Sort the values in input Arrays
+///
+/// Sort an multidimensional Array along a given dimension
+///
+/// # Parameters
+///
+/// - `input` - Input Array
+/// - `dim` - Dimension along which to sort
+/// - `ascending` - Sorted output will have ascending values if
+///                 ```True``` and descending order otherwise.
+///
+/// # Return Values
+///
+/// Sorted Array.
+pub fn sort<T>(input: &Array<T>, dim: u32, ascending: bool) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_sort(&mut temp as *mut af_array, input.get(), dim, ascending);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Sort the values in input Arrays
+///
+/// # Parameters
+///
+/// - `input` - Input Array
+/// - `dim` - Dimension along which to sort
+/// - `ascending` - Sorted output will have ascending values if
+///                 ```True``` and descending order otherwise.
+///
+/// # Return Values
+///
+/// A tuple of Arrays.
+///
+/// The first Array contains the keys based on sorted values.
+///
+/// The second Array contains the original indices of the sorted values.
+pub fn sort_index<T>(input: &Array<T>, dim: u32, ascending: bool) -> (Array<T>, Array<u32>)
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let mut idx: af_array = std::ptr::null_mut();
+        let err_val = af_sort_index(
+            &mut temp as *mut af_array,
+            &mut idx as *mut af_array,
+            input.get(),
+            dim,
+            ascending,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (temp.into(), idx.into())
+    }
+}
+
+/// Sort the values in input Arrays
+///
+/// Sort an multidimensional Array based on keys
+///
+/// # Parameters
+///
+/// - `keys` - Array with key values
+/// - `vals` - Array with input values
+/// - `dim` - Dimension along which to sort
+/// - `ascending` - Sorted output will have ascending values if ```True``` and descending order otherwise.
+///
+/// # Return Values
+///
+/// A tuple of Arrays.
+///
+/// The first Array contains the keys based on sorted values.
+///
+/// The second Array contains the sorted values.
+pub fn sort_by_key<K, V>(
+    keys: &Array<K>,
+    vals: &Array<V>,
+    dim: u32,
+    ascending: bool,
+) -> (Array<K>, Array<V>)
+where
+    K: HasAfEnum + RealNumber,
+    V: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let mut temp2: af_array = std::ptr::null_mut();
+        let err_val = af_sort_by_key(
+            &mut temp as *mut af_array,
+            &mut temp2 as *mut af_array,
+            keys.get(),
+            vals.get(),
+            dim,
+            ascending,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (temp.into(), temp2.into())
+    }
+}
+
+/// Find unique values from a Set
+///
+/// # Parameters
+///
+/// - `input` - Input Array
+/// - `is_sorted` - is a boolean variable. If ```True``
+///                 indicates, the `input` Array is sorted.
+///
+/// # Return Values
+///
+/// An Array of unique values from the input Array.
+pub fn set_unique<T>(input: &Array<T>, is_sorted: bool) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_set_unique(&mut temp as *mut af_array, input.get(), is_sorted);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find union of two sets
+///
+/// # Parameters
+///
+/// - `first` is one of the input sets
+/// - `second` is the other of the input sets
+/// - `is_unique` is a boolean value indicates if the input sets are unique
+///
+/// # Return Values
+///
+/// An Array with union of the input sets
+pub fn set_union<T>(first: &Array<T>, second: &Array<T>, is_unique: bool) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_set_union(
+            &mut temp as *mut af_array,
+            first.get(),
+            second.get(),
+            is_unique,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find intersection of two sets
+///
+/// # Parameters
+///
+/// - `first` is one of the input sets
+/// - `second` is the other of the input sets
+/// - `is_unique` is a boolean value indicates if the input sets are unique
+///
+/// # Return Values
+///
+/// An Array with intersection of the input sets
+pub fn set_intersect<T>(first: &Array<T>, second: &Array<T>, is_unique: bool) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_set_intersect(
+            &mut temp as *mut af_array,
+            first.get(),
+            second.get(),
+            is_unique,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Generalized scan
+///
+/// # Parameters
+///
+/// - `input` is the data on which scan is to be performed
+/// - `dim` is the dimension along which scan operation is to be performed
+/// - `op` takes value of [BinaryOp](./enum.BinaryOp.html) enum indicating
+///    the type of scan operation
+/// - `inclusive` says if inclusive/exclusive scan is to be performed
+///
+/// # Return Values
+///
+/// Output Array of scanned input
+pub fn scan<T>(
+    input: &Array<T>,
+    dim: i32,
+    op: BinaryOp,
+    inclusive: bool,
+) -> Array<T::AggregateOutType>
+where
+    T: HasAfEnum,
+    T::AggregateOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_scan(
+            &mut temp as *mut af_array,
+            input.get(),
+            dim,
+            op as u32,
+            inclusive,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Generalized scan by key
+///
+/// # Parameters
+///
+/// - `key` is the key Array
+/// - `input` is the data on which scan is to be performed
+/// - `dim` is the dimension along which scan operation is to be performed
+/// - `op` takes value of [BinaryOp](./enum.BinaryOp.html) enum indicating
+///    the type of scan operation
+/// - `inclusive` says if inclusive/exclusive scan is to be performed
+///
+/// # Return Values
+///
+/// Output Array of scanned input
+pub fn scan_by_key<K, V>(
+    key: &Array<K>,
+    input: &Array<V>,
+    dim: i32,
+    op: BinaryOp,
+    inclusive: bool,
+) -> Array<V::AggregateOutType>
+where
+    V: HasAfEnum,
+    V::AggregateOutType: HasAfEnum,
+    K: HasAfEnum + Scanable,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_scan_by_key(
+            &mut temp as *mut af_array,
+            key.get(),
+            input.get(),
+            dim,
+            op as u32,
+            inclusive,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! dim_reduce_by_key_func_def {
+    ($brief_str: expr, $ex_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => {
+        #[doc=$brief_str]
+        /// # Parameters
+        ///
+        /// - `keys` - key Array
+        /// - `vals` - value Array
+        /// - `dim`   - Dimension along which the input Array is reduced
+        ///
+        /// # Return Values
+        ///
+        /// Tuple of Arrays, with output keys and values after reduction
+        ///
+        #[doc=$ex_str]
+        pub fn $fn_name<KeyType, ValueType>(keys: &Array<KeyType>, vals: &Array<ValueType>,
+                                            dim: i32
+        ) -> (Array<KeyType>, Array<$out_type>)
+        where
+            KeyType: ReduceByKeyInput,
+            ValueType: HasAfEnum,
+            $out_type: HasAfEnum,
+        {
+            unsafe {
+            let mut out_keys: af_array = std::ptr::null_mut();
+            let mut out_vals: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut out_keys as *mut af_array, &mut out_vals as *mut af_array,
+                    keys.get(), vals.get(), dim,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            (out_keys.into(), out_vals.into())
+            }
+        }
+    };
+}
+
+dim_reduce_by_key_func_def!(
+    "
+Key based AND of elements along a given dimension
+
+All positive non-zero values are considered true, while negative and zero
+values are considered as false.
+",
+    "
+# Examples
+```rust
+use arrayfire::{Dim4, print, randu, all_true_by_key};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let vals = randu::<f32>(dims);
+let keys = randu::<u32>(Dim4::new(&[5, 1, 1, 1]));
+print(&vals);
+print(&keys);
+let (out_keys, out_vals) = all_true_by_key(&keys, &vals, 0);
+print(&out_keys);
+print(&out_vals);
+```
+",
+    all_true_by_key,
+    af_all_true_by_key,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "
+Key based OR of elements along a given dimension
+
+All positive non-zero values are considered true, while negative and zero
+values are considered as false.
+",
+    "
+# Examples
+```rust
+use arrayfire::{Dim4, print, randu, any_true_by_key};
+let dims = Dim4::new(&[5, 3, 1, 1]);
+let vals = randu::<f32>(dims);
+let keys = randu::<u32>(Dim4::new(&[5, 1, 1, 1]));
+print(&vals);
+print(&keys);
+let (out_keys, out_vals) = any_true_by_key(&keys, &vals, 0);
+print(&out_keys);
+print(&out_vals);
+```
+",
+    any_true_by_key,
+    af_any_true_by_key,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "Find total count of elements with similar keys along a given dimension",
+    "",
+    count_by_key,
+    af_count_by_key,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "Find maximum among values of similar keys along a given dimension",
+    "",
+    max_by_key,
+    af_max_by_key,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "Find minimum among values of similar keys along a given dimension",
+    "",
+    min_by_key,
+    af_min_by_key,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "Find product of all values with similar keys along a given dimension",
+    "",
+    product_by_key,
+    af_product_by_key,
+    ValueType::ProductOutType
+);
+
+dim_reduce_by_key_func_def!(
+    "Find sum of all values with similar keys along a given dimension",
+    "",
+    sum_by_key,
+    af_sum_by_key,
+    ValueType::AggregateOutType
+);
+
+macro_rules! dim_reduce_by_key_nan_func_def {
+    ($brief_str: expr, $ex_str: expr, $fn_name: ident, $ffi_name: ident, $out_type: ty) => {
+        #[doc=$brief_str]
+        ///
+        /// This version of sum by key can replaced all NaN values in the input
+        /// with a user provided value before performing the reduction operation.
+        /// # Parameters
+        ///
+        /// - `keys` - key Array
+        /// - `vals` - value Array
+        /// - `dim`   - Dimension along which the input Array is reduced
+        ///
+        /// # Return Values
+        ///
+        /// Tuple of Arrays, with output keys and values after reduction
+        ///
+        #[doc=$ex_str]
+        pub fn $fn_name<KeyType, ValueType>(keys: &Array<KeyType>, vals: &Array<ValueType>,
+                                            dim: i32, replace_value: f64
+        ) -> (Array<KeyType>, Array<$out_type>)
+        where
+            KeyType: ReduceByKeyInput,
+            ValueType: HasAfEnum,
+            $out_type: HasAfEnum,
+        {
+            unsafe {
+            let mut out_keys: af_array = std::ptr::null_mut();
+            let mut out_vals: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut out_keys as *mut af_array,
+                    &mut out_vals as *mut af_array,
+                    keys.get(), vals.get(), dim, replace_value,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            (out_keys.into(), out_vals.into())
+            }
+        }
+    };
+}
+
+dim_reduce_by_key_nan_func_def!(
+    "Compute sum of all values with similar keys along a given dimension",
+    "",
+    sum_by_key_nan,
+    af_sum_by_key_nan,
+    ValueType::AggregateOutType
+);
+
+dim_reduce_by_key_nan_func_def!(
+    "Compute product of all values with similar keys along a given dimension",
+    "",
+    product_by_key_nan,
+    af_product_by_key_nan,
+    ValueType::ProductOutType
+);
+
+/// Max reduction along given axis as per ragged lengths provided
+///
+/// # Parameters
+///
+/// - `input` contains the input values to be reduced
+/// - `ragged_len` array containing number of elements to use when reducing along `dim`
+/// - `dim` is the dimension along which the max operation occurs
+///
+/// # Return Values
+///
+/// Tuple of Arrays:
+/// - First element: An Array containing the maximum ragged values in `input` along `dim`
+///                  according to `ragged_len`
+/// - Second Element: An Array containing the locations of the maximum ragged values in
+///                   `input` along `dim` according to `ragged_len`
+///
+/// # Examples
+/// ```rust
+/// use arrayfire::{Array, dim4, print, randu, max_ragged};
+/// let vals: [f32; 6] = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0];
+/// let rlens: [u32; 2] = [9, 2];
+/// let varr = Array::new(&vals, dim4![3, 2]);
+/// let rarr = Array::new(&rlens, dim4![1, 2]);
+/// print(&varr);
+/// // 1 4
+/// // 2 5
+/// // 3 6
+/// print(&rarr); // numbers of elements to participate in reduction along given axis
+/// // 9 2
+/// let (out, idx) = max_ragged(&varr, &rarr, 0);
+/// print(&out);
+/// // 3 5
+/// print(&idx);
+/// // 2 1 //Since 3 is max element for given length 9 along first column
+///        //Since 5 is max element for given length 2 along second column
+/// ```
+pub fn max_ragged<T>(
+    input: &Array<T>,
+    ragged_len: &Array<u32>,
+    dim: i32,
+) -> (Array<T::InType>, Array<u32>)
+where
+    T: HasAfEnum,
+    T::InType: HasAfEnum,
+{
+    unsafe {
+        let mut out_vals: af_array = std::ptr::null_mut();
+        let mut out_idxs: af_array = std::ptr::null_mut();
+        let err_val = af_max_ragged(
+            &mut out_vals as *mut af_array,
+            &mut out_idxs as *mut af_array,
+            input.get(),
+            ragged_len.get(),
+            dim,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (out_vals.into(), out_idxs.into())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::core::c32;
+    use super::{imax_all, imin_all, product_nan_all, sum_all, sum_nan_all};
+    use crate::core::set_device;
+    use crate::randu;
+
+    #[test]
+    fn all_reduce_api() {
+        set_device(0);
+        let a = randu!(c32; 10, 10);
+        println!("Reduction of complex f32 matrix: {:?}", sum_all(&a));
+
+        let b = randu!(bool; 10, 10);
+        println!("reduction of bool matrix: {:?}", sum_all(&b));
+
+        println!(
+            "reduction of complex f32 matrix after replacing nan with {}: {:?}",
+            1.0,
+            product_nan_all(&a, 1.0)
+        );
+
+        println!(
+            "reduction of bool matrix after replacing nan with {}: {:?}",
+            0.0,
+            sum_nan_all(&b, 0.0)
+        );
+    }
+
+    #[test]
+    fn all_ireduce_api() {
+        set_device(0);
+        let a = randu!(c32; 10);
+        println!("Reduction of complex f32 matrix: {:?}", imin_all(&a));
+
+        let b = randu!(u32; 10);
+        println!("reduction of bool matrix: {:?}", imax_all(&b));
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/blas/mod.rs.html b/src/arrayfire/blas/mod.rs.html new file mode 100644 index 000000000..f8f1ad8ec --- /dev/null +++ b/src/arrayfire/blas/mod.rs.html @@ -0,0 +1,537 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+
+use super::core::{
+    af_array, AfError, Array, CublasMathMode, FloatingPoint, HasAfEnum, MatProp, HANDLE_ERROR,
+};
+
+use libc::{c_int, c_uint, c_void};
+use std::vec::Vec;
+
+extern "C" {
+    fn af_gemm(
+        out: *mut af_array,
+        optlhs: c_uint,
+        optrhs: c_uint,
+        alpha: *const c_void,
+        lhs: af_array,
+        rhs: af_array,
+        beta: *const c_void,
+    ) -> c_int;
+
+    fn af_matmul(
+        out: *mut af_array,
+        lhs: af_array,
+        rhs: af_array,
+        optlhs: c_uint,
+        optrhs: c_uint,
+    ) -> c_int;
+
+    fn af_dot(
+        out: *mut af_array,
+        lhs: af_array,
+        rhs: af_array,
+        optlhs: c_uint,
+        optrhs: c_uint,
+    ) -> c_int;
+
+    fn af_transpose(out: *mut af_array, arr: af_array, conjugate: bool) -> c_int;
+    fn af_transpose_inplace(arr: af_array, conjugate: bool) -> c_int;
+
+    fn afcu_cublasSetMathMode(mode: c_int) -> c_int;
+}
+
+/// BLAS general matrix multiply (GEMM) of two Array objects
+///
+///
+/// This provides a general interface to the BLAS level 3 general matrix multiply (GEMM),
+/// which is generally defined as:
+///
+/// \begin{equation}
+///     C = \alpha * opA(A)opB(B) + \beta * C
+/// \end{equation}
+///
+///   where $\alpha$ (**alpha**) and $\beta$ (**beta**) are both scalars; $A$ and $B$ are the matrix
+///   multiply operands; and $opA$ and $opB$ are noop
+///   (if optLhs is [MatProp::NONE](./enum.MatProp.html)) or transpose
+///   (if optLhs is [MatProp::TRANS](./enum.MatProp.html)) operations on $A$ or $B$ before the
+///   actual GEMM operation. Batched GEMM is supported if at least either $A$ or $B$ have more than
+///   two dimensions (see [af::matmul](http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b)
+///   for more details on broadcasting). However, only one **alpha** and one **beta** can be used
+///   for all of the batched matrix operands.
+///
+///   The `output` Array can be used both as an input and output. An allocation will be performed
+///   if you pass an empty Array (i.e. `let c: Array<f32> = (0 as i64).into();`). If a valid Array
+///   is passed as $C$, the operation will be performed on that Array itself. The C Array must be
+///   the correct type and shape; otherwise, an error will be thrown.
+///
+///   Note: Passing an Array that has not been initialized to the C array
+///   will cause undefined behavior.
+///
+/// # Examples
+///
+/// Given below is an example of using gemm API with existing Arrays
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, print, randu, gemm};
+///
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+///
+/// let alpha = vec![1.0 as f32];
+/// let  beta = vec![2.0 as f32];
+///
+/// let lhs = randu::<f32>(dims);
+/// let rhs = randu::<f32>(dims);
+///
+/// let mut result = Array::new_empty(dims);
+/// gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE,
+///      alpha, &lhs, &rhs, beta);
+/// ```
+///
+/// If you don't have an existing Array, you can also use gemm in the following fashion.
+/// However, if there is no existing Array that you need to fill and your use case doesn't
+/// deal with alpha and beta from gemm equation, it is recommended to use
+/// [matmul](./fn.matmul.html) for more terse code.
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, af_array, print, randu, gemm};
+///
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+///
+/// let alpha = vec![1.0 as f32];
+/// let  beta = vec![2.0 as f32];
+///
+/// let lhs = randu::<f32>(dims);
+/// let rhs = randu::<f32>(dims);
+///
+/// let mut result: Array::<f32> = (std::ptr::null_mut() as af_array).into();
+///
+/// gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE,
+///      alpha, &lhs, &rhs, beta);
+/// ```
+///
+/// # Parameters
+///
+/// - `optlhs` - Transpose left hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html)
+/// - `optrhs` - Transpose right hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html)
+/// - `alpha` is alpha value;
+/// - `lhs` is the Array on left hand side
+/// - `rhs` is the Array on right hand side
+/// - `beta` is beta value;
+///
+/// # Return Values
+///
+/// Array, result of gemm operation
+pub fn gemm<T>(
+    output: &mut Array<T>,
+    optlhs: MatProp,
+    optrhs: MatProp,
+    alpha: Vec<T>,
+    lhs: &Array<T>,
+    rhs: &Array<T>,
+    beta: Vec<T>,
+) where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut out = output.get();
+        let err_val = af_gemm(
+            &mut out as *mut af_array,
+            optlhs as c_uint,
+            optrhs as c_uint,
+            alpha.as_ptr() as *const c_void,
+            lhs.get(),
+            rhs.get(),
+            beta.as_ptr() as *const c_void,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        output.set(out);
+    }
+}
+
+/// Matrix multiple of two Arrays
+///
+/// # Parameters
+///
+/// - `lhs` is the Array on left hand side
+/// - `rhs` is the Array on right hand side
+/// - `optlhs` - Transpose left hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html)
+/// - `optrhs` - Transpose right hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html)
+///
+/// # Return Values
+///
+/// The result Array of matrix multiplication
+pub fn matmul<T>(lhs: &Array<T>, rhs: &Array<T>, optlhs: MatProp, optrhs: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_matmul(
+            &mut temp as *mut af_array,
+            lhs.get(),
+            rhs.get(),
+            optlhs as c_uint,
+            optrhs as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Calculate the dot product of vectors.
+///
+/// Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors.
+///
+/// # Parameters
+///
+/// - `lhs` - Left hand side of dot operation
+/// - `rhs` - Right hand side of dot operation
+/// - `optlhs` - Options for lhs. Currently only NONE value from [MatProp](./enum.MatProp.html) is supported.
+/// - `optrhs` - Options for rhs. Currently only NONE value from [MatProp](./enum.MatProp.html) is supported.
+///
+/// # Return Values
+///
+/// The result of dot product.
+pub fn dot<T>(lhs: &Array<T>, rhs: &Array<T>, optlhs: MatProp, optrhs: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_dot(
+            &mut temp as *mut af_array,
+            lhs.get(),
+            rhs.get(),
+            optlhs as c_uint,
+            optrhs as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Transpose of a matrix.
+///
+/// # Parameters
+///
+/// - `arr` is the input Array
+/// - `conjugate` is a boolean that indicates if the transpose operation needs to be a conjugate
+/// transpose
+///
+/// # Return Values
+///
+/// Transposed Array.
+pub fn transpose<T: HasAfEnum>(arr: &Array<T>, conjugate: bool) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_transpose(&mut temp as *mut af_array, arr.get(), conjugate);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inplace transpose of a matrix.
+///
+/// # Parameters
+///
+/// - `arr` is the input Array that has to be transposed
+/// - `conjugate` is a boolean that indicates if the transpose operation needs to be a conjugate
+/// transpose
+pub fn transpose_inplace<T: HasAfEnum>(arr: &mut Array<T>, conjugate: bool) {
+    unsafe {
+        let err_val = af_transpose_inplace(arr.get(), conjugate);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Sets the cuBLAS math mode for the internal handle.
+///
+/// See the cuBLAS documentation for additional details
+///
+/// # Parameters
+///
+/// - `mode` takes a value of [CublasMathMode](./enum.CublasMathMode.html) enum
+pub fn set_cublas_mode(mode: CublasMathMode) {
+    unsafe {
+        afcu_cublasSetMathMode(mode as c_int);
+        //let err_val = afcu_cublasSetMathMode(mode as c_int);
+        // FIXME(wonder if this something to throw off,
+        // the program state is not invalid or anything
+        // HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/arith.rs.html b/src/arrayfire/core/arith.rs.html new file mode 100644 index 000000000..9651ed418 --- /dev/null +++ b/src/arrayfire/core/arith.rs.html @@ -0,0 +1,1999 @@ +arith.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+
+use super::array::Array;
+use super::data::{constant, tile, ConstGenerator};
+use super::defines::AfError;
+use super::dim4::Dim4;
+use super::error::HANDLE_ERROR;
+use super::util::{af_array, HasAfEnum, ImplicitPromote, IntegralType};
+use num::Zero;
+
+use libc::c_int;
+use num::Complex;
+use std::mem;
+use std::ops::Neg;
+use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub};
+
+extern "C" {
+    fn af_add(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_sub(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_mul(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_div(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+
+    fn af_lt(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_gt(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_le(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_ge(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_eq(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_or(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+
+    fn af_neq(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_and(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_rem(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_mod(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+
+    fn af_bitand(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_bitor(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_bitxor(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_bitshiftl(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_bitshiftr(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_minof(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_maxof(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_clamp(
+        out: *mut af_array,
+        inp: af_array,
+        lo: af_array,
+        hi: af_array,
+        batch: bool,
+    ) -> c_int;
+
+    fn af_not(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_abs(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_arg(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_sign(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_ceil(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_round(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_trunc(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_floor(out: *mut af_array, arr: af_array) -> c_int;
+
+    fn af_hypot(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+
+    fn af_sin(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_cos(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_tan(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_asin(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_acos(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_atan(out: *mut af_array, arr: af_array) -> c_int;
+
+    fn af_atan2(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_cplx2(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_root(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+    fn af_pow(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int;
+
+    fn af_cplx(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_real(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_imag(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_conjg(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_sinh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_cosh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_tanh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_asinh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_acosh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_atanh(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_pow2(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_exp(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_sigmoid(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_expm1(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_erf(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_erfc(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_log(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_log1p(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_log10(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_log2(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_sqrt(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_rsqrt(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_cbrt(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_factorial(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_tgamma(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_lgamma(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_iszero(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_isinf(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_isnan(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_bitnot(out: *mut af_array, arr: af_array) -> c_int;
+}
+
+/// Enables use of `!` on objects of type [Array](./struct.Array.html)
+impl<'f, T> Not for &'f Array<T>
+where
+    T: HasAfEnum,
+{
+    type Output = Array<T>;
+
+    fn not(self) -> Self::Output {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_not(&mut temp as *mut af_array, self.get());
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+macro_rules! unary_func {
+    [$doc_str: expr, $fn_name: ident, $ffi_fn: ident, $out_type: ident] => (
+        #[doc=$doc_str]
+        ///
+        /// This is an element wise unary operation.
+        pub fn $fn_name<T: HasAfEnum>(input: &Array<T>) -> Array< T::$out_type >
+        where T::$out_type: HasAfEnum {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_fn(&mut temp as *mut af_array, input.get());
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    )
+}
+
+unary_func!("Computes absolute value", abs, af_abs, AbsOutType);
+unary_func!("Computes phase value", arg, af_arg, ArgOutType);
+
+unary_func!(
+    "Truncate the values in an Array",
+    trunc,
+    af_trunc,
+    AbsOutType
+);
+unary_func!(
+    "Computes the sign of input Array values",
+    sign,
+    af_sign,
+    AbsOutType
+);
+unary_func!("Round the values in an Array", round, af_round, AbsOutType);
+unary_func!("Floor the values in an Array", floor, af_floor, AbsOutType);
+unary_func!("Ceil the values in an Array", ceil, af_ceil, AbsOutType);
+
+unary_func!("Compute sigmoid function", sigmoid, af_sigmoid, AbsOutType);
+unary_func!(
+    "Compute e raised to the power of value -1",
+    expm1,
+    af_expm1,
+    AbsOutType
+);
+unary_func!("Compute error function value", erf, af_erf, AbsOutType);
+unary_func!(
+    "Compute the complementary error function value",
+    erfc,
+    af_erfc,
+    AbsOutType
+);
+
+unary_func!("Compute logarithm base 10", log10, af_log10, AbsOutType);
+unary_func!(
+    "Compute the logarithm of input Array + 1",
+    log1p,
+    af_log1p,
+    AbsOutType
+);
+unary_func!("Compute logarithm base 2", log2, af_log2, AbsOutType);
+
+unary_func!("Compute the cube root", cbrt, af_cbrt, AbsOutType);
+unary_func!("Compute gamma function", tgamma, af_tgamma, AbsOutType);
+unary_func!(
+    "Compute the logarithm of absolute values of gamma function",
+    lgamma,
+    af_lgamma,
+    AbsOutType
+);
+
+unary_func!("Compute acosh", acosh, af_acosh, UnaryOutType);
+unary_func!("Compute acos", acos, af_acos, UnaryOutType);
+unary_func!("Compute asin", asin, af_asin, UnaryOutType);
+unary_func!("Compute asinh", asinh, af_asinh, UnaryOutType);
+unary_func!("Compute atan", atan, af_atan, UnaryOutType);
+unary_func!("Compute atanh", atanh, af_atanh, UnaryOutType);
+unary_func!("Compute cos", cos, af_cos, UnaryOutType);
+unary_func!("Compute cosh", cosh, af_cosh, UnaryOutType);
+unary_func!(
+    "Compute e raised to the power of value",
+    exp,
+    af_exp,
+    UnaryOutType
+);
+unary_func!("Compute the natural logarithm", log, af_log, UnaryOutType);
+unary_func!("Compute sin", sin, af_sin, UnaryOutType);
+unary_func!("Compute sinh", sinh, af_sinh, UnaryOutType);
+unary_func!("Compute the square root", sqrt, af_sqrt, UnaryOutType);
+unary_func!(
+    "Compute the reciprocal square root",
+    rsqrt,
+    af_rsqrt,
+    UnaryOutType
+);
+unary_func!("Compute tan", tan, af_tan, UnaryOutType);
+unary_func!("Compute tanh", tanh, af_tanh, UnaryOutType);
+
+unary_func!(
+    "Extract real values from a complex Array",
+    real,
+    af_real,
+    AbsOutType
+);
+unary_func!(
+    "Extract imaginary values from a complex Array",
+    imag,
+    af_imag,
+    AbsOutType
+);
+unary_func!(
+    "Create a complex Array from real Array",
+    cplx,
+    af_cplx,
+    ComplexOutType
+);
+unary_func!(
+    "Compute the complex conjugate",
+    conjg,
+    af_conjg,
+    ComplexOutType
+);
+unary_func!(
+    "Compute two raised to the power of value",
+    pow2,
+    af_pow2,
+    UnaryOutType
+);
+unary_func!(
+    "Compute the factorial",
+    factorial,
+    af_factorial,
+    UnaryOutType
+);
+
+macro_rules! unary_boolean_func {
+    [$doc_str: expr, $fn_name: ident, $ffi_fn: ident] => (
+        #[doc=$doc_str]
+        ///
+        /// This is an element wise unary operation.
+        pub fn $fn_name<T: HasAfEnum>(input: &Array<T>) -> Array<bool> {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_fn(&mut temp as *mut af_array, input.get());
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    )
+}
+
+unary_boolean_func!("Check if values are zero", iszero, af_iszero);
+unary_boolean_func!("Check if values are infinity", isinf, af_isinf);
+unary_boolean_func!("Check if values are NaN", isnan, af_isnan);
+
+macro_rules! binary_func {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => {
+        #[doc=$doc_str]
+        ///
+        /// This is an element wise binary operation.
+        ///
+        /// # Important Notes
+        ///
+        /// - If shape/dimensions of `lhs` and `rhs` are same, the value of `batch` parameter
+        ///   has no effect.
+        ///
+        /// - If shape/dimensions of `lhs` and `rhs` are different, the value of `batch` has
+        ///   to be set to `true`. In this case, the shapes of `lhs` and `rhs` have to satisfy the
+        ///   following criteria:
+        ///   - Same number of elements in `lhs` and `rhs` along a given dimension/axis
+        ///   - Only one element in `lhs` or `rhs` along a given dimension/axis
+        pub fn $fn_name<A, B>(lhs: &Array<A>, rhs: &Array<B>, batch: bool) -> Array<A::Output>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_fn(
+                    &mut temp as *mut af_array, lhs.get(), rhs.get(), batch,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+                Into::<Array<A::Output>>::into(temp)
+            }
+        }
+    };
+}
+
+binary_func!(
+    "Elementwise AND(bit) operation of two Arrays",
+    bitand,
+    af_bitand
+);
+binary_func!(
+    "Elementwise OR(bit) operation of two Arrays",
+    bitor,
+    af_bitor
+);
+binary_func!(
+    "Elementwise XOR(bit) operation of two Arrays",
+    bitxor,
+    af_bitxor
+);
+binary_func!(
+    "Elementwise not equals comparison of two Arrays",
+    neq,
+    af_neq
+);
+binary_func!(
+    "Elementwise logical and operation of two Arrays",
+    and,
+    af_and
+);
+binary_func!("Elementwise logical or operation of two Arrays", or, af_or);
+binary_func!(
+    "Elementwise minimum operation of two Arrays",
+    minof,
+    af_minof
+);
+binary_func!(
+    "Elementwise maximum operation of two Arrays",
+    maxof,
+    af_maxof
+);
+binary_func!(
+    "Compute length of hypotenuse of two Arrays",
+    hypot,
+    af_hypot
+);
+
+/// Type Trait to convert to an [Array](./struct.Array.html)
+///
+/// Generic functions that overload the binary operations such as add, div, mul, rem, ge etc. are
+/// bound by this trait to allow combinations of scalar values and Array objects as parameters
+/// to those functions.
+///
+/// Internally, Convertable trait is implemented by following types.
+///
+/// - f32
+/// - f64
+/// - num::Complex\<f32\>
+/// - num::Complex\<f64\>
+/// - bool
+/// - i32
+/// - u32
+/// - u8
+/// - i64
+/// - u64
+/// - i16
+/// - u16
+///
+pub trait Convertable {
+    /// This type alias always points to `Self` which is the
+    /// type of [Array](./struct.Array.html) returned by the
+    /// trait method [convert](./trait.Convertable.html#tymethod.convert).
+    type OutType: HasAfEnum;
+
+    /// Get an Array of implementors type
+    fn convert(&self) -> Array<Self::OutType>;
+}
+
+impl<T> Convertable for T
+where
+    T: Clone + ConstGenerator<OutType = T>,
+{
+    type OutType = T;
+
+    fn convert(&self) -> Array<Self::OutType> {
+        constant(self.clone(), Dim4::new(&[1, 1, 1, 1]))
+    }
+}
+
+impl<T: HasAfEnum> Convertable for Array<T> {
+    type OutType = T;
+
+    fn convert(&self) -> Array<Self::OutType> {
+        self.clone()
+    }
+}
+
+macro_rules! overloaded_binary_func {
+    ($doc_str: expr, $fn_name: ident, $help_name: ident, $ffi_name: ident) => {
+        fn $help_name<A, B>(lhs: &Array<A>, rhs: &Array<B>, batch: bool) -> Array<A::Output>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array, lhs.get(), rhs.get(), batch,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+
+        #[doc=$doc_str]
+        ///
+        /// This is a binary elementwise operation.
+        ///
+        ///# Parameters
+        ///
+        /// - `arg1`is an argument that implements an internal trait `Convertable`.
+        /// - `arg2`is an argument that implements an internal trait `Convertable`.
+        /// - `batch` is an boolean that indicates if the current operation is an batch operation.
+        ///
+        /// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral
+        /// type.
+        ///
+        ///# Return Values
+        ///
+        /// An Array with results of the binary operation.
+        ///
+        ///# Important Notes
+        ///
+        /// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter
+        ///   has no effect.
+        ///
+        /// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has
+        ///   to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the
+        ///   following criteria:
+        ///   - Same number of elements in `arg1` and `arg2` along a given dimension/axis
+        ///   - Only one element in `arg1` or `arg2` along a given dimension/axis
+        ///
+        /// - The trait `Convertable` essentially translates to a scalar native type on rust or Array.
+        pub fn $fn_name<T, U>(
+            arg1: &T,
+            arg2: &U,
+            batch: bool,
+        ) -> Array<
+            <<T as Convertable>::OutType as ImplicitPromote<<U as Convertable>::OutType>>::Output,
+        >
+        where
+            T: Convertable,
+            U: Convertable,
+            <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
+            <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>,
+        {
+            let lhs = arg1.convert(); // Convert to Array<T>
+            let rhs = arg2.convert(); // Convert to Array<T>
+            match (lhs.is_scalar(), rhs.is_scalar()) {
+                (true, false) => {
+                    let l = tile(&lhs, rhs.dims());
+                    $help_name(&l, &rhs, batch)
+                }
+                (false, true) => {
+                    let r = tile(&rhs, lhs.dims());
+                    $help_name(&lhs, &r, batch)
+                }
+                _ => $help_name(&lhs, &rhs, batch),
+            }
+        }
+    };
+}
+
+overloaded_binary_func!("Addition of two Arrays", add, add_helper, af_add);
+overloaded_binary_func!("Subtraction of two Arrays", sub, sub_helper, af_sub);
+overloaded_binary_func!("Multiplication of two Arrays", mul, mul_helper, af_mul);
+overloaded_binary_func!("Division of two Arrays", div, div_helper, af_div);
+overloaded_binary_func!("Compute remainder from two Arrays", rem, rem_helper, af_rem);
+overloaded_binary_func!("Compute left shift", shiftl, shiftl_helper, af_bitshiftl);
+overloaded_binary_func!("Compute right shift", shiftr, shiftr_helper, af_bitshiftr);
+overloaded_binary_func!(
+    "Compute modulo of two Arrays",
+    modulo,
+    modulo_helper,
+    af_mod
+);
+overloaded_binary_func!(
+    "Calculate atan2 of two Arrays",
+    atan2,
+    atan2_helper,
+    af_atan2
+);
+overloaded_binary_func!(
+    "Create complex array from two Arrays",
+    cplx2,
+    cplx2_helper,
+    af_cplx2
+);
+overloaded_binary_func!("Compute root", root, root_helper, af_root);
+overloaded_binary_func!("Computer power", pow, pow_helper, af_pow);
+
+macro_rules! overloaded_compare_func {
+    ($doc_str: expr, $fn_name: ident, $help_name: ident, $ffi_name: ident) => {
+        fn $help_name<A, B>(lhs: &Array<A>, rhs: &Array<B>, batch: bool) -> Array<bool>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array, lhs.get(), rhs.get(), batch,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+
+        #[doc=$doc_str]
+        ///
+        /// This is a comparison operation.
+        ///
+        ///# Parameters
+        ///
+        /// - `arg1`is an argument that implements an internal trait `Convertable`.
+        /// - `arg2`is an argument that implements an internal trait `Convertable`.
+        /// - `batch` is an boolean that indicates if the current operation is an batch operation.
+        ///
+        /// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral
+        /// type.
+        ///
+        ///# Return Values
+        ///
+        /// An Array with results of the comparison operation a.k.a an Array of boolean values.
+        ///
+        ///# Important Notes
+        ///
+        /// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter
+        ///   has no effect.
+        ///
+        /// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has
+        ///   to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the
+        ///   following criteria:
+        ///   - Same number of elements in `arg1` and `arg2` along a given dimension/axis
+        ///   - Only one element in `arg1` or `arg2` along a given dimension/axis
+        ///
+        /// - The trait `Convertable` essentially translates to a scalar native type on rust or Array.
+        pub fn $fn_name<T, U>(
+            arg1: &T,
+            arg2: &U,
+            batch: bool,
+        ) -> Array<bool>
+        where
+            T: Convertable,
+            U: Convertable,
+            <T as Convertable>::OutType: ImplicitPromote<<U as Convertable>::OutType>,
+            <U as Convertable>::OutType: ImplicitPromote<<T as Convertable>::OutType>,
+        {
+            let lhs = arg1.convert(); // Convert to Array<T>
+            let rhs = arg2.convert(); // Convert to Array<T>
+            match (lhs.is_scalar(), rhs.is_scalar()) {
+                (true, false) => {
+                    let l = tile(&lhs, rhs.dims());
+                    $help_name(&l, &rhs, batch)
+                }
+                (false, true) => {
+                    let r = tile(&rhs, lhs.dims());
+                    $help_name(&lhs, &r, batch)
+                }
+                _ => $help_name(&lhs, &rhs, batch),
+            }
+        }
+    };
+}
+
+overloaded_compare_func!(
+    "Perform `less than` comparison operation",
+    lt,
+    lt_helper,
+    af_lt
+);
+overloaded_compare_func!(
+    "Perform `greater than` comparison operation",
+    gt,
+    gt_helper,
+    af_gt
+);
+overloaded_compare_func!(
+    "Perform `less than equals` comparison operation",
+    le,
+    le_helper,
+    af_le
+);
+overloaded_compare_func!(
+    "Perform `greater than equals` comparison operation",
+    ge,
+    ge_helper,
+    af_ge
+);
+overloaded_compare_func!(
+    "Perform `equals` comparison operation",
+    eq,
+    eq_helper,
+    af_eq
+);
+
+fn clamp_helper<X, Y>(
+    inp: &Array<X>,
+    lo: &Array<Y>,
+    hi: &Array<Y>,
+    batch: bool,
+) -> Array<<X as ImplicitPromote<Y>>::Output>
+where
+    X: ImplicitPromote<Y>,
+    Y: ImplicitPromote<X>,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_clamp(
+            &mut temp as *mut af_array,
+            inp.get(),
+            lo.get(),
+            hi.get(),
+            batch,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Clamp the values of Array
+///
+/// # Parameters
+///
+/// - `arg1`is an argument that implements an internal trait `Convertable`.
+/// - `arg2`is an argument that implements an internal trait `Convertable`.
+/// - `batch` is an boolean that indicates if the current operation is an batch operation.
+///
+/// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral
+/// type.
+///
+/// # Return Values
+///
+/// An Array with results of the binary operation.
+///
+/// # Important Notes
+///
+/// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter
+///   has no effect.
+///
+/// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has
+///   to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the
+///   following criteria:
+///   - Same number of elements in `arg1` and `arg2` along a given dimension/axis
+///   - Only one element in `arg1` or `arg2` along a given dimension/axis
+///
+/// - The trait `Convertable` essentially translates to a scalar native type on rust or Array.
+pub fn clamp<T, C>(
+    input: &Array<T>,
+    arg1: &C,
+    arg2: &C,
+    batch: bool,
+) -> Array<<T as ImplicitPromote<<C as Convertable>::OutType>>::Output>
+where
+    T: ImplicitPromote<<C as Convertable>::OutType>,
+    C: Convertable,
+    <C as Convertable>::OutType: ImplicitPromote<T>,
+{
+    let lo = arg1.convert(); // Convert to Array<T>
+    let hi = arg2.convert(); // Convert to Array<T>
+    match (lo.is_scalar(), hi.is_scalar()) {
+        (true, false) => {
+            let l = tile(&lo, hi.dims());
+            clamp_helper(&input, &l, &hi, batch)
+        }
+        (false, true) => {
+            let r = tile(&hi, lo.dims());
+            clamp_helper(&input, &lo, &r, batch)
+        }
+        (true, true) => {
+            let l = tile(&lo, input.dims());
+            let r = tile(&hi, input.dims());
+            clamp_helper(&input, &l, &r, batch)
+        }
+        _ => clamp_helper(&input, &lo, &hi, batch),
+    }
+}
+
+macro_rules! arith_rhs_scalar_func {
+    ($op_name:ident, $fn_name: ident) => {
+        // Implement (&Array<T> op_name rust_type)
+        impl<'f, T, U> $op_name<U> for &'f Array<T>
+        where
+            T: ImplicitPromote<U>,
+            U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>,
+        {
+            type Output = Array<<T as ImplicitPromote<U>>::Output>;
+
+            fn $fn_name(self, rhs: U) -> Self::Output {
+                let temp = rhs.clone();
+                $fn_name(self, &temp, false)
+            }
+        }
+
+        // Implement (Array<T> op_name rust_type)
+        impl<T, U> $op_name<U> for Array<T>
+        where
+            T: ImplicitPromote<U>,
+            U: ImplicitPromote<T> + Clone + ConstGenerator<OutType = U>,
+        {
+            type Output = Array<<T as ImplicitPromote<U>>::Output>;
+
+            fn $fn_name(self, rhs: U) -> Self::Output {
+                let temp = rhs.clone();
+                $fn_name(&self, &temp, false)
+            }
+        }
+    };
+}
+
+macro_rules! arith_lhs_scalar_func {
+    ($rust_type: ty, $op_name: ident, $fn_name: ident) => {
+        // Implement (rust_type op_name &Array<T>)
+        impl<'f, T> $op_name<&'f Array<T>> for $rust_type
+        where
+            T: ImplicitPromote<$rust_type>,
+            $rust_type: ImplicitPromote<T>,
+        {
+            type Output = Array<<$rust_type as ImplicitPromote<T>>::Output>;
+
+            fn $fn_name(self, rhs: &'f Array<T>) -> Self::Output {
+                $fn_name(&self, rhs, false)
+            }
+        }
+
+        // Implement (rust_type op_name Array<T>)
+        impl<T> $op_name<Array<T>> for $rust_type
+        where
+            T: ImplicitPromote<$rust_type>,
+            $rust_type: ImplicitPromote<T>,
+        {
+            type Output = Array<<$rust_type as ImplicitPromote<T>>::Output>;
+
+            fn $fn_name(self, rhs: Array<T>) -> Self::Output {
+                $fn_name(&self, &rhs, false)
+            }
+        }
+    };
+}
+
+arith_rhs_scalar_func!(Add, add);
+arith_rhs_scalar_func!(Sub, sub);
+arith_rhs_scalar_func!(Mul, mul);
+arith_rhs_scalar_func!(Div, div);
+
+macro_rules! arith_scalar_spec {
+    ($ty_name:ty) => {
+        arith_lhs_scalar_func!($ty_name, Add, add);
+        arith_lhs_scalar_func!($ty_name, Sub, sub);
+        arith_lhs_scalar_func!($ty_name, Mul, mul);
+        arith_lhs_scalar_func!($ty_name, Div, div);
+    };
+}
+
+arith_scalar_spec!(Complex<f64>);
+arith_scalar_spec!(Complex<f32>);
+arith_scalar_spec!(f64);
+arith_scalar_spec!(f32);
+arith_scalar_spec!(u64);
+arith_scalar_spec!(i64);
+arith_scalar_spec!(u32);
+arith_scalar_spec!(i32);
+arith_scalar_spec!(u8);
+
+macro_rules! arith_func {
+    ($op_name:ident, $fn_name:ident, $delegate:ident) => {
+        impl<A, B> $op_name<Array<B>> for Array<A>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            type Output = Array<<A as ImplicitPromote<B>>::Output>;
+
+            fn $fn_name(self, rhs: Array<B>) -> Self::Output {
+                $delegate(&self, &rhs, false)
+            }
+        }
+
+        impl<'a, A, B> $op_name<&'a Array<B>> for Array<A>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            type Output = Array<<A as ImplicitPromote<B>>::Output>;
+
+            fn $fn_name(self, rhs: &'a Array<B>) -> Self::Output {
+                $delegate(&self, rhs, false)
+            }
+        }
+
+        impl<'a, A, B> $op_name<Array<B>> for &'a Array<A>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            type Output = Array<<A as ImplicitPromote<B>>::Output>;
+
+            fn $fn_name(self, rhs: Array<B>) -> Self::Output {
+                $delegate(self, &rhs, false)
+            }
+        }
+
+        impl<'a, 'b, A, B> $op_name<&'a Array<B>> for &'b Array<A>
+        where
+            A: ImplicitPromote<B>,
+            B: ImplicitPromote<A>,
+        {
+            type Output = Array<<A as ImplicitPromote<B>>::Output>;
+
+            fn $fn_name(self, rhs: &'a Array<B>) -> Self::Output {
+                $delegate(self, rhs, false)
+            }
+        }
+    };
+}
+
+arith_func!(Add, add, add);
+arith_func!(Sub, sub, sub);
+arith_func!(Mul, mul, mul);
+arith_func!(Div, div, div);
+arith_func!(Rem, rem, rem);
+arith_func!(Shl, shl, shiftl);
+arith_func!(Shr, shr, shiftr);
+arith_func!(BitAnd, bitand, bitand);
+arith_func!(BitOr, bitor, bitor);
+arith_func!(BitXor, bitxor, bitxor);
+
+macro_rules! bitshift_scalar_func {
+    ($rust_type: ty, $trait_name: ident, $op_name: ident) => {
+        impl<T> $trait_name<$rust_type> for Array<T>
+        where
+            T: ImplicitPromote<$rust_type>,
+            $rust_type: ImplicitPromote<T>,
+        {
+            type Output = Array<<T as ImplicitPromote<$rust_type>>::Output>;
+
+            fn $op_name(self, rhs: $rust_type) -> Self::Output {
+                let op2 = constant(rhs, self.dims());
+                self.$op_name(op2)
+            }
+        }
+        impl<'f, T> $trait_name<$rust_type> for &'f Array<T>
+        where
+            T: ImplicitPromote<$rust_type>,
+            $rust_type: ImplicitPromote<T>,
+        {
+            type Output = Array<<T as ImplicitPromote<$rust_type>>::Output>;
+
+            fn $op_name(self, rhs: $rust_type) -> Self::Output {
+                let op2 = constant(rhs, self.dims());
+                self.$op_name(op2)
+            }
+        }
+    };
+}
+
+macro_rules! shift_spec {
+    ($trait_name: ident, $op_name: ident) => {
+        bitshift_scalar_func!(u64, $trait_name, $op_name);
+        bitshift_scalar_func!(u32, $trait_name, $op_name);
+        bitshift_scalar_func!(u16, $trait_name, $op_name);
+        bitshift_scalar_func!(u8, $trait_name, $op_name);
+    };
+}
+
+shift_spec!(Shl, shl);
+shift_spec!(Shr, shr);
+
+#[cfg(op_assign)]
+mod op_assign {
+
+    use super::*;
+    use crate::core::{assign_gen, Array, Indexer, Seq};
+    use std::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
+    use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
+
+    macro_rules! arith_assign_func {
+        ($op_name:ident, $fn_name:ident, $func: ident) => {
+            impl<A, B> $op_name<Array<B>> for Array<A>
+            where
+                A: ImplicitPromote<B>,
+                B: ImplicitPromote<A>,
+            {
+                fn $fn_name(&mut self, rhs: Array<B>) {
+                    let tmp_seq = Seq::<f32>::default();
+                    let mut idxrs = Indexer::default();
+                    for n in 0..self.numdims() {
+                        idxrs.set_index(&tmp_seq, n, Some(false));
+                    }
+                    let opres = $func(self as &Array<A>, &rhs, false).cast::<A>();
+                    assign_gen(self, &idxrs, &opres);
+                }
+            }
+        };
+    }
+
+    arith_assign_func!(AddAssign, add_assign, add);
+    arith_assign_func!(SubAssign, sub_assign, sub);
+    arith_assign_func!(MulAssign, mul_assign, mul);
+    arith_assign_func!(DivAssign, div_assign, div);
+    arith_assign_func!(RemAssign, rem_assign, rem);
+    arith_assign_func!(ShlAssign, shl_assign, shiftl);
+    arith_assign_func!(ShrAssign, shr_assign, shiftr);
+
+    macro_rules! shift_assign_func {
+        ($rust_type:ty, $trait_name:ident, $op_name:ident, $func:ident) => {
+            impl<T> $trait_name<$rust_type> for Array<T>
+            where
+                $rust_type: ImplicitPromote<T>,
+                T: ImplicitPromote<$rust_type, Output = T>,
+            {
+                fn $op_name(&mut self, rhs: $rust_type) {
+                    let mut temp = $func(self, &rhs, false);
+                    mem::swap(self, &mut temp);
+                }
+            }
+        };
+    }
+
+    macro_rules! shift_assign_spec {
+        ($trait_name: ident, $op_name: ident, $func:ident) => {
+            shift_assign_func!(u64, $trait_name, $op_name, $func);
+            shift_assign_func!(u32, $trait_name, $op_name, $func);
+            shift_assign_func!(u16, $trait_name, $op_name, $func);
+            shift_assign_func!(u8, $trait_name, $op_name, $func);
+        };
+    }
+
+    shift_assign_spec!(ShlAssign, shl_assign, shiftl);
+    shift_assign_spec!(ShrAssign, shr_assign, shiftr);
+
+    macro_rules! bit_assign_func {
+        ($op_name:ident, $fn_name:ident, $func: ident) => {
+            impl<A, B> $op_name<Array<B>> for Array<A>
+            where
+                A: ImplicitPromote<B>,
+                B: ImplicitPromote<A>,
+            {
+                fn $fn_name(&mut self, rhs: Array<B>) {
+                    let tmp_seq = Seq::<f32>::default();
+                    let mut idxrs = Indexer::default();
+                    for n in 0..self.numdims() {
+                        idxrs.set_index(&tmp_seq, n, Some(false));
+                    }
+                    let opres = $func(self as &Array<A>, &rhs, false).cast::<A>();
+                    assign_gen(self, &idxrs, &opres);
+                }
+            }
+        };
+    }
+
+    bit_assign_func!(BitAndAssign, bitand_assign, bitand);
+    bit_assign_func!(BitOrAssign, bitor_assign, bitor);
+    bit_assign_func!(BitXorAssign, bitxor_assign, bitxor);
+}
+
+///Implement negation trait for Array
+impl<T> Neg for Array<T>
+where
+    T: Zero + ConstGenerator<OutType = T>,
+{
+    type Output = Array<T>;
+
+    fn neg(self) -> Self::Output {
+        let cnst = constant(T::zero(), self.dims());
+        sub(&cnst, &self, true)
+    }
+}
+
+/// Perform bitwise complement on all values of Array
+pub fn bitnot<T: HasAfEnum>(input: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + IntegralType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_bitnot(&mut temp as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/array.rs.html b/src/arrayfire/core/array.rs.html new file mode 100644 index 000000000..a3086c30c --- /dev/null +++ b/src/arrayfire/core/array.rs.html @@ -0,0 +1,2387 @@ +array.rs - source + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+
+use super::defines::{AfError, Backend, DType};
+use super::dim4::Dim4;
+use super::error::HANDLE_ERROR;
+use super::util::{af_array, dim_t, void_ptr, HasAfEnum};
+
+use libc::{c_char, c_int, c_longlong, c_uint, c_void};
+use std::ffi::CString;
+use std::marker::PhantomData;
+
+// Some unused functions from array.h in C-API of ArrayFire
+// af_copy_array
+// af_write_array
+// af_get_data_ref_count
+
+extern "C" {
+    fn af_create_array(
+        out: *mut af_array,
+        data: *const c_void,
+        ndims: c_uint,
+        dims: *const dim_t,
+        aftype: c_uint,
+    ) -> c_int;
+
+    fn af_create_handle(
+        out: *mut af_array,
+        ndims: c_uint,
+        dims: *const dim_t,
+        aftype: c_uint,
+    ) -> c_int;
+
+    fn af_device_array(
+        out: *mut af_array,
+        data: *mut c_void,
+        ndims: c_uint,
+        dims: *const dim_t,
+        aftype: c_uint,
+    ) -> c_int;
+
+    fn af_get_elements(out: *mut dim_t, arr: af_array) -> c_int;
+
+    fn af_get_type(out: *mut c_uint, arr: af_array) -> c_int;
+
+    fn af_get_dims(
+        dim0: *mut c_longlong,
+        dim1: *mut c_longlong,
+        dim2: *mut c_longlong,
+        dim3: *mut c_longlong,
+        arr: af_array,
+    ) -> c_int;
+
+    fn af_get_numdims(result: *mut c_uint, arr: af_array) -> c_int;
+
+    fn af_is_empty(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_scalar(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_row(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_column(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_vector(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_complex(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_real(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_double(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_single(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_half(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_integer(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_bool(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_realfloating(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_floating(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_linear(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_owner(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_is_sparse(result: *mut bool, arr: af_array) -> c_int;
+
+    fn af_get_data_ptr(data: *mut c_void, arr: af_array) -> c_int;
+
+    fn af_eval(arr: af_array) -> c_int;
+
+    fn af_eval_multiple(num: c_int, arrays: *const af_array) -> c_int;
+
+    fn af_set_manual_eval_flag(flag: c_int) -> c_int;
+
+    fn af_get_manual_eval_flag(flag: *mut c_int) -> c_int;
+
+    fn af_retain_array(out: *mut af_array, arr: af_array) -> c_int;
+
+    fn af_copy_array(out: *mut af_array, arr: af_array) -> c_int;
+
+    fn af_release_array(arr: af_array) -> c_int;
+
+    //fn af_print_array(arr: af_array) -> c_int;
+
+    fn af_print_array_gen(exp: *const c_char, arr: af_array, precision: c_int) -> c_int;
+
+    fn af_cast(out: *mut af_array, arr: af_array, aftype: c_uint) -> c_int;
+
+    fn af_get_backend_id(backend: *mut c_uint, input: af_array) -> c_int;
+
+    fn af_get_device_id(device: *mut c_int, input: af_array) -> c_int;
+
+    fn af_create_strided_array(
+        arr: *mut af_array,
+        data: *const c_void,
+        offset: dim_t,
+        ndims: c_uint,
+        dims: *const dim_t,
+        strides: *const dim_t,
+        aftype: c_uint,
+        stype: c_uint,
+    ) -> c_int;
+
+    fn af_get_strides(
+        s0: *mut dim_t,
+        s1: *mut dim_t,
+        s2: *mut dim_t,
+        s3: *mut dim_t,
+        arr: af_array,
+    ) -> c_int;
+
+    fn af_get_offset(offset: *mut dim_t, arr: af_array) -> c_int;
+
+    fn af_lock_array(arr: af_array) -> c_int;
+
+    fn af_unlock_array(arr: af_array) -> c_int;
+
+    fn af_get_device_ptr(ptr: *mut void_ptr, arr: af_array) -> c_int;
+
+    fn af_get_allocated_bytes(result: *mut usize, arr: af_array) -> c_int;
+}
+
+/// A multidimensional data container
+///
+/// Currently, Array objects can store only data until four dimensions
+///
+/// ## Sharing Across Threads
+///
+/// While sharing an Array with other threads, there is no need to wrap
+/// this in an Arc object unless only one such object is required to exist.
+/// The reason being that ArrayFire's internal Array is appropriately reference
+/// counted in thread safe manner. However, if you need to modify Array object,
+/// then please do wrap the object using a Mutex or Read-Write lock.
+///
+/// Examples on how to share Array across threads is illustrated in our
+/// [book](http://arrayfire.org/arrayfire-rust/book/multi-threading.html)
+///
+/// ### NOTE
+///
+/// All operators(traits) from std::ops module implemented for Array object
+/// carry out element wise operations. For example, `*` does multiplication of
+/// elements at corresponding locations in two different Arrays.
+pub struct Array<T: HasAfEnum> {
+    handle: af_array,
+    /// The phantom marker denotes the
+    /// allocation of data on compute device
+    _marker: PhantomData<T>,
+}
+
+/// Enable safely moving Array objects across threads
+unsafe impl<T: HasAfEnum> Send for Array<T> {}
+
+unsafe impl<T: HasAfEnum> Sync for Array<T> {}
+
+macro_rules! is_func {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => (
+        #[doc=$doc_str]
+        pub fn $fn_name(&self) -> bool {
+            unsafe {
+                let mut ret_val: bool = false;
+                let err_val = $ffi_fn(&mut ret_val as *mut bool, self.handle);
+                HANDLE_ERROR(AfError::from(err_val));
+                ret_val
+            }
+        }
+    )
+}
+
+impl<T> Array<T>
+where
+    T: HasAfEnum,
+{
+    /// Constructs a new Array object
+    ///
+    /// # Examples
+    ///
+    /// An example of creating an Array from f32 array
+    ///
+    /// ```rust
+    /// use arrayfire::{Array, Dim4, print};
+    /// let values: [f32; 3] = [1.0, 2.0, 3.0];
+    /// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+    /// print(&indices);
+    /// ```
+    /// An example of creating an Array from half::f16 array
+    ///
+    /// ```rust
+    /// use arrayfire::{Array, Dim4, is_half_available, print};
+    /// use half::f16;
+    ///
+    /// let values: [f32; 3] = [1.0, 2.0, 3.0];
+    ///
+    /// if is_half_available(0) { // Default device is 0, hence the argument
+    ///     let half_values = values.iter().map(|&x| f16::from_f32(x)).collect::<Vec<_>>();
+    ///
+    ///     let hvals = Array::new(&half_values, Dim4::new(&[3, 1, 1, 1]));
+    ///
+    ///     print(&hvals);
+    /// } else {
+    ///     println!("Half support isn't available on this device");
+    /// }
+    /// ```
+    ///
+    pub fn new(slice: &[T], dims: Dim4) -> Self {
+        let aftype = T::get_af_dtype();
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_create_array(
+                &mut temp as *mut af_array,
+                slice.as_ptr() as *const c_void,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const c_longlong,
+                aftype as c_uint,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    /// Constructs a new Array object from strided data
+    ///
+    /// The data pointed by the slice passed to this function can possibily be offseted using an additional `offset` parameter.
+    pub fn new_strided(slice: &[T], offset: i64, dims: Dim4, strides: Dim4) -> Self {
+        let aftype = T::get_af_dtype();
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_create_strided_array(
+                &mut temp as *mut af_array,
+                slice.as_ptr() as *const c_void,
+                offset as dim_t,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const c_longlong,
+                strides.get().as_ptr() as *const c_longlong,
+                aftype as c_uint,
+                1 as c_uint,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    /// Constructs a new Array object of specified dimensions and type
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use arrayfire::{Array, Dim4};
+    /// let garbage_vals = Array::<f32>::new_empty(Dim4::new(&[3, 1, 1, 1]));
+    /// ```
+    pub fn new_empty(dims: Dim4) -> Self {
+        let aftype = T::get_af_dtype();
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_create_handle(
+                &mut temp as *mut af_array,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const c_longlong,
+                aftype as c_uint,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    /// Constructs a new Array object from device pointer
+    ///
+    /// The example show cases the usage using CUDA API, but usage of this function will
+    /// be similar in CPU and OpenCL backends also. In the case of OpenCL backend, the pointer
+    /// would be cl_mem. A short example of how to create an Array from device pointer is
+    /// shown below but for detailed set of examples, please check out the tutorial book
+    /// pages:
+    ///  - [Interoperability with CUDA][1]
+    ///  - [Interoperability with OpenCL][2]
+    ///
+    ///  [1]: http://arrayfire.org/arrayfire-rust/book/cuda-interop.html
+    ///  [2]: http://arrayfire.org/arrayfire-rust/book/opencl-interop.html
+    ///
+    /// # Examples
+    ///
+    /// An example of creating an Array device pointer using
+    /// [rustacuda](https://github.com/bheisler/RustaCUDA) crate. The
+    /// example has to be copied to a `bin` crate with following contents in Cargo.toml
+    /// to run successfully. Note that, all required setup for rustacuda and arrayfire crate
+    /// have to completed first.
+    /// ```text
+    /// [package]
+    /// ....
+    /// [dependencies]
+    /// rustacuda = "0.1"
+    /// rustacuda_derive = "0.1"
+    /// rustacuda_core = "0.1"
+    /// arrayfire = "3.7.*"
+    /// ```
+    ///
+    /// ```rust,ignore
+    ///use arrayfire::*;
+    ///use rustacuda::*;
+    ///use rustacuda::prelude::*;
+    ///
+    ///fn main() {
+    ///    let v: Vec<_> = (0u8 .. 100).map(f32::from).collect();
+    ///
+    ///    rustacuda::init(CudaFlags::empty());
+    ///    let device = Device::get_device(0).unwrap();
+    ///    let context = Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO,
+    ///                                           device).unwrap();
+    ///    // Approach 1
+    ///    {
+    ///        let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap();
+    ///
+    ///        let array_dptr = Array::new_from_device_ptr(
+    ///            buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10));
+    ///
+    ///        af_print!("array_dptr", &array_dptr);
+    ///
+    ///        array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership
+    ///    }
+    ///
+    ///    // Approach 2
+    ///    {
+    ///        let mut dptr: *mut f32 = std::ptr::null_mut();
+    ///        unsafe {
+    ///            dptr = memory::cuda_malloc::<f32>(10*10).unwrap().as_raw_mut();
+    ///        }
+    ///        let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10));
+    ///        // note that values might be garbage in the memory pointed out by dptr
+    ///        // in this example as it is allocated but not initialized prior to passing
+    ///        // along to arrayfire::Array::new*
+    ///
+    ///        // After ArrayFire takes over ownership of the pointer, you can use other
+    ///        // arrayfire functions as usual.
+    ///        af_print!("array_dptr", &array_dptr);
+    ///    }
+    ///}
+    /// ```
+    pub fn new_from_device_ptr(dev_ptr: *mut T, dims: Dim4) -> Self {
+        let aftype = T::get_af_dtype();
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_device_array(
+                &mut temp as *mut af_array,
+                dev_ptr as *mut c_void,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+                aftype as c_uint,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    /// Returns the backend of the Array
+    ///
+    /// # Return Values
+    ///
+    /// Returns an value of type `Backend` which indicates which backend
+    /// was active when Array was created.
+    pub fn get_backend(&self) -> Backend {
+        unsafe {
+            let mut ret_val: u32 = 0;
+            let err_val = af_get_backend_id(&mut ret_val as *mut c_uint, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            match (err_val, ret_val) {
+                (0, 1) => Backend::CPU,
+                (0, 2) => Backend::CUDA,
+                (0, 3) => Backend::OPENCL,
+                _ => Backend::DEFAULT,
+            }
+        }
+    }
+
+    /// Returns the device identifier(integer) on which the Array was created
+    ///
+    /// # Return Values
+    ///
+    /// Return the device id on which Array was created.
+    pub fn get_device_id(&self) -> i32 {
+        unsafe {
+            let mut ret_val: i32 = 0;
+            let err_val = af_get_device_id(&mut ret_val as *mut c_int, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            ret_val
+        }
+    }
+
+    /// Returns the number of elements in the Array
+    pub fn elements(&self) -> usize {
+        unsafe {
+            let mut ret_val: dim_t = 0;
+            let err_val = af_get_elements(&mut ret_val as *mut dim_t, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            ret_val as usize
+        }
+    }
+
+    /// Returns the Array data type
+    pub fn get_type(&self) -> DType {
+        unsafe {
+            let mut ret_val: u32 = 0;
+            let err_val = af_get_type(&mut ret_val as *mut c_uint, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            DType::from(ret_val)
+        }
+    }
+
+    /// Returns the dimensions of the Array
+    pub fn dims(&self) -> Dim4 {
+        unsafe {
+            let mut ret0: i64 = 0;
+            let mut ret1: i64 = 0;
+            let mut ret2: i64 = 0;
+            let mut ret3: i64 = 0;
+            let err_val = af_get_dims(
+                &mut ret0 as *mut dim_t,
+                &mut ret1 as *mut dim_t,
+                &mut ret2 as *mut dim_t,
+                &mut ret3 as *mut dim_t,
+                self.handle,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])
+        }
+    }
+
+    /// Returns the strides of the Array
+    pub fn strides(&self) -> Dim4 {
+        unsafe {
+            let mut ret0: i64 = 0;
+            let mut ret1: i64 = 0;
+            let mut ret2: i64 = 0;
+            let mut ret3: i64 = 0;
+            let err_val = af_get_strides(
+                &mut ret0 as *mut dim_t,
+                &mut ret1 as *mut dim_t,
+                &mut ret2 as *mut dim_t,
+                &mut ret3 as *mut dim_t,
+                self.handle,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])
+        }
+    }
+
+    /// Returns the number of dimensions of the Array
+    pub fn numdims(&self) -> u32 {
+        unsafe {
+            let mut ret_val: u32 = 0;
+            let err_val = af_get_numdims(&mut ret_val as *mut c_uint, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            ret_val
+        }
+    }
+
+    /// Returns the offset to the pointer from where data begins
+    pub fn offset(&self) -> i64 {
+        unsafe {
+            let mut ret_val: i64 = 0;
+            let err_val = af_get_offset(&mut ret_val as *mut dim_t, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            ret_val
+        }
+    }
+
+    /// Returns the native FFI handle for Rust object `Array`
+    pub unsafe fn get(&self) -> af_array {
+        self.handle
+    }
+
+    /// Set the native FFI handle for Rust object `Array`
+    pub fn set(&mut self, handle: af_array) {
+        self.handle = handle;
+    }
+
+    /// Copies the data from the Array to the mutable slice `data`
+    ///
+    /// # Examples
+    ///
+    /// Basic case
+    /// ```
+    /// # use arrayfire::{Array,Dim4,HasAfEnum};
+    /// let a:Vec<u8> = vec![0,1,2,3,4,5,6,7,8];
+    /// let b = Array::<u8>::new(&a,Dim4::new(&[3,3,1,1]));
+    /// let mut c = vec!(u8::default();b.elements());
+    /// b.host(&mut c);
+    /// assert_eq!(c,a);
+    /// ```
+    /// Generic case
+    /// ```
+    /// # use arrayfire::{Array,Dim4,HasAfEnum};
+    /// fn to_vec<T:HasAfEnum+Default+Clone>(array:&Array<T>) -> Vec<T> {
+    ///     let mut vec = vec!(T::default();array.elements());
+    ///     array.host(&mut vec);
+    ///     return vec;
+    /// }
+    ///
+    /// let a = Array::<u8>::new(&[0,1,2,3,4,5,6,7,8],Dim4::new(&[3,3,1,1]));
+    /// let b:Vec<u8> = vec![0,1,2,3,4,5,6,7,8];
+    /// assert_eq!(to_vec(&a),b);
+    /// ```
+    pub fn host<O: HasAfEnum>(&self, data: &mut [O]) {
+        if data.len() != self.elements() {
+            HANDLE_ERROR(AfError::ERR_SIZE);
+        }
+        unsafe {
+            let err_val = af_get_data_ptr(data.as_mut_ptr() as *mut c_void, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Evaluates any pending lazy expressions that represent the data in the Array object
+    pub fn eval(&self) {
+        unsafe {
+            let err_val = af_eval(self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Makes an copy of the Array
+    ///
+    /// This does a deep copy of the data into a new Array
+    pub fn copy(&self) -> Self {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_copy_array(&mut temp as *mut af_array, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    is_func!("Check if Array is empty", is_empty, af_is_empty);
+    is_func!("Check if Array is scalar", is_scalar, af_is_scalar);
+    is_func!("Check if Array is a row", is_row, af_is_row);
+    is_func!("Check if Array is a column", is_column, af_is_column);
+    is_func!("Check if Array is a vector", is_vector, af_is_vector);
+
+    is_func!(
+        "Check if Array is of real (not complex) type",
+        is_real,
+        af_is_real
+    );
+    is_func!(
+        "Check if Array is of complex type",
+        is_complex,
+        af_is_complex
+    );
+
+    is_func!(
+        "Check if Array's numerical type is of double precision",
+        is_double,
+        af_is_double
+    );
+    is_func!(
+        "Check if Array's numerical type is of single precision",
+        is_single,
+        af_is_single
+    );
+    is_func!(
+        "Check if Array's numerical type is of half precision",
+        is_half,
+        af_is_half
+    );
+    is_func!(
+        "Check if Array is of integral type",
+        is_integer,
+        af_is_integer
+    );
+    is_func!("Check if Array is of boolean type", is_bool, af_is_bool);
+
+    is_func!(
+        "Check if Array is floating point real(not complex) data type",
+        is_realfloating,
+        af_is_realfloating
+    );
+    is_func!(
+        "Check if Array is floating point type, either real or complex data",
+        is_floating,
+        af_is_floating
+    );
+
+    is_func!(
+        "Check if Array's memory layout is continuous and one dimensional",
+        is_linear,
+        af_is_linear
+    );
+    is_func!("Check if Array is a sparse matrix", is_sparse, af_is_sparse);
+    is_func!(
+        "Check if Array's memory is owned by it and not a view of another Array",
+        is_owner,
+        af_is_owner
+    );
+
+    /// Cast the Array data type to `target_type`
+    pub fn cast<O: HasAfEnum>(&self) -> Array<O> {
+        let trgt_type = O::get_af_dtype();
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_cast(&mut temp as *mut af_array, self.handle, trgt_type as c_uint);
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+
+    /// Lock the device buffer in the memory manager
+    ///
+    /// Locked buffers are not freed by memory manager until unlock is called.
+    pub fn lock(&self) {
+        unsafe {
+            let err_val = af_lock_array(self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Unlock the device buffer in the memory manager
+    ///
+    /// This function will give back the control over the device pointer to the
+    /// memory manager.
+    pub fn unlock(&self) {
+        unsafe {
+            let err_val = af_unlock_array(self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Get the device pointer and lock the buffer in memory manager
+    ///
+    /// The device pointer is not freed by memory manager until unlock is called.
+    pub unsafe fn device_ptr(&self) -> void_ptr {
+        let mut temp: void_ptr = std::ptr::null_mut();
+        let err_val = af_get_device_ptr(&mut temp as *mut void_ptr, self.handle);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp
+    }
+
+    /// Get the size of physical allocated bytes.
+    ///
+    /// This function will return the size of the parent/owner if the current Array object is an
+    /// indexed Array.
+    pub fn get_allocated_bytes(&self) -> usize {
+        unsafe {
+            let mut temp: usize = 0;
+            let err_val = af_get_allocated_bytes(&mut temp as *mut usize, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            temp
+        }
+    }
+}
+
+/// Used for creating Array object from native
+/// resource id, an 64 bit integer
+impl<T: HasAfEnum> Into<Array<T>> for af_array {
+    fn into(self) -> Array<T> {
+        Array {
+            handle: self,
+            _marker: PhantomData,
+        }
+    }
+}
+
+/// Returns a new Array object after incrementing the reference count of native resource
+///
+/// Cloning an Array does not do a deep copy of the underlying array data. It increments the
+/// reference count of native resource and returns you the new reference in the form a new Array
+/// object.
+///
+/// To create a deep copy use
+/// [copy()](./struct.Array.html#method.copy)
+impl<T> Clone for Array<T>
+where
+    T: HasAfEnum,
+{
+    fn clone(&self) -> Self {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let ret_val = af_retain_array(&mut temp as *mut af_array, self.handle);
+            match ret_val {
+                0 => temp.into(),
+                _ => panic!("Weak copy of Array failed with error code: {}", ret_val),
+            }
+        }
+    }
+}
+
+/// To free resources when Array goes out of scope
+impl<T> Drop for Array<T>
+where
+    T: HasAfEnum,
+{
+    fn drop(&mut self) {
+        unsafe {
+            let ret_val = af_release_array(self.handle);
+            match ret_val {
+                0 => (),
+                _ => panic!("Array<T> drop failed with error code: {}", ret_val),
+            }
+        }
+    }
+}
+
+/// Print data in the Array
+///
+/// # Parameters
+///
+/// - `input` is the Array to be printed
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, print, randu};
+/// println!("Create a 5-by-3 matrix of random floats on the GPU");
+/// let dims = Dim4::new(&[5, 3, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// print(&a);
+/// ```
+///
+/// The sample output will look like below:
+///
+/// ```text
+/// [5 3 1 1]
+///     0.7402     0.4464     0.7762
+///     0.9210     0.6673     0.2948
+///     0.0390     0.1099     0.7140
+///     0.9690     0.4702     0.3585
+///     0.9251     0.5132     0.6814
+/// ```
+pub fn print<T: HasAfEnum>(input: &Array<T>) {
+    let emptystring = CString::new("").unwrap();
+    unsafe {
+        let err_val = af_print_array_gen(
+            emptystring.to_bytes_with_nul().as_ptr() as *const c_char,
+            input.get(),
+            4,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Generalized Array print function
+///
+/// Use this function to print Array data with arbitrary preicsion
+///
+/// # Parameters
+///
+/// - `msg` is message to be printed before printing the Array data
+/// - `input` is the Array to be printed
+/// - `precision` is data precision with which Array has to be printed
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, print_gen, randu};
+/// println!("Create a 5-by-3 matrix of random floats on the GPU");
+/// let dims = Dim4::new(&[5, 3, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// print_gen(String::from("Random Array"), &a, Some(6));
+/// ```
+///
+/// The sample output will look like below:
+///
+/// ```text
+/// Random Array
+///
+/// [5 3 1 1]
+///     0.740276     0.446440     0.776202
+///     0.921094     0.667321     0.294810
+///     0.039014     0.109939     0.714090
+///     0.969058     0.470269     0.358590
+///     0.925181     0.513225     0.681451
+/// ```
+pub fn print_gen<T: HasAfEnum>(msg: String, input: &Array<T>, precision: Option<i32>) {
+    let emptystring = CString::new(msg.as_bytes()).unwrap();
+    unsafe {
+        let err_val = af_print_array_gen(
+            emptystring.to_bytes_with_nul().as_ptr() as *const c_char,
+            input.get(),
+            match precision {
+                Some(p) => p,
+                None => 4,
+            } as c_int,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// evaluate multiple arrays
+///
+/// Use this function to evaluate multiple arrays in single call
+///
+/// # Parameters
+///
+/// - `inputs` are the list of arrays to be evaluated
+pub fn eval_multiple<T: HasAfEnum>(inputs: Vec<&Array<T>>) {
+    unsafe {
+        let mut v = Vec::new();
+        for i in inputs {
+            v.push(i.get());
+        }
+
+        let err_val = af_eval_multiple(v.len() as c_int, v.as_ptr() as *const af_array);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Set eval flag value
+///
+/// This function can be used to toggle on/off the manual evaluation of arrays.
+///
+/// # Parameters
+///
+/// - `flag` is a boolean value indicating manual evaluation setting
+pub fn set_manual_eval(flag: bool) {
+    unsafe {
+        let err_val = af_set_manual_eval_flag(flag as c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get eval flag value
+///
+/// This function can be used to find out if manual evaluation of arrays is
+/// turned on or off.
+///
+/// # Return Values
+///
+/// A boolean indicating manual evaluation setting.
+pub fn is_eval_manual() -> bool {
+    unsafe {
+        let mut ret_val: i32 = 0;
+        let err_val = af_get_manual_eval_flag(&mut ret_val as *mut c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        ret_val > 0
+    }
+}
+
+#[cfg(feature = "afserde")]
+mod afserde {
+    // Reimport required from super scope
+    use super::{Array, DType, Dim4, HasAfEnum};
+
+    use serde::de::{Deserializer, Error, Unexpected};
+    use serde::ser::Serializer;
+    use serde::{Deserialize, Serialize};
+
+    #[derive(Debug, Serialize, Deserialize)]
+    struct ArrayOnHost<T: HasAfEnum + std::fmt::Debug> {
+        dtype: DType,
+        shape: Dim4,
+        data: Vec<T>,
+    }
+
+    /// Serialize Implementation of Array
+    impl<T> Serialize for Array<T>
+    where
+        T: std::default::Default + std::clone::Clone + Serialize + HasAfEnum + std::fmt::Debug,
+    {
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            let mut vec = vec![T::default(); self.elements()];
+            self.host(&mut vec);
+            let arr_on_host = ArrayOnHost {
+                dtype: self.get_type(),
+                shape: self.dims().clone(),
+                data: vec,
+            };
+            arr_on_host.serialize(serializer)
+        }
+    }
+
+    /// Deserialize Implementation of Array
+    impl<'de, T> Deserialize<'de> for Array<T>
+    where
+        T: Deserialize<'de> + HasAfEnum + std::fmt::Debug,
+    {
+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+        where
+            D: Deserializer<'de>,
+        {
+            match ArrayOnHost::<T>::deserialize(deserializer) {
+                Ok(arr_on_host) => {
+                    let read_dtype = arr_on_host.dtype;
+                    let expected_dtype = T::get_af_dtype();
+                    if expected_dtype != read_dtype {
+                        let error_msg = format!(
+                            "data type is {:?}, deserialized type is {:?}",
+                            expected_dtype, read_dtype
+                        );
+                        return Err(Error::invalid_value(Unexpected::Enum, &error_msg.as_str()));
+                    }
+                    Ok(Array::<T>::new(
+                        &arr_on_host.data,
+                        arr_on_host.shape.clone(),
+                    ))
+                }
+                Err(err) => Err(err),
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::array::print;
+    use super::super::data::constant;
+    use super::super::device::{info, set_device, sync};
+    use crate::dim4;
+    use std::sync::{mpsc, Arc, RwLock};
+    use std::thread;
+
+    #[test]
+    fn thread_move_array() {
+        // ANCHOR: move_array_to_thread
+        set_device(0);
+        info();
+        let mut a = constant(1, dim4!(3, 3));
+
+        let handle = thread::spawn(move || {
+            //set_device to appropriate device id is required in each thread
+            set_device(0);
+
+            println!("\nFrom thread {:?}", thread::current().id());
+
+            a += constant(2, dim4!(3, 3));
+            print(&a);
+        });
+
+        //Need to join other threads as main thread holds arrayfire context
+        handle.join().unwrap();
+        // ANCHOR_END: move_array_to_thread
+    }
+
+    #[test]
+    fn thread_borrow_array() {
+        set_device(0);
+        info();
+        let a = constant(1i32, dim4!(3, 3));
+
+        let handle = thread::spawn(move || {
+            set_device(0); //set_device to appropriate device id is required in each thread
+            println!("\nFrom thread {:?}", thread::current().id());
+            print(&a);
+        });
+        //Need to join other threads as main thread holds arrayfire context
+        handle.join().unwrap();
+    }
+
+    // ANCHOR: multiple_threads_enum_def
+    #[derive(Debug, Copy, Clone)]
+    enum Op {
+        Add,
+        Sub,
+        Div,
+        Mul,
+    }
+    // ANCHOR_END: multiple_threads_enum_def
+
+    #[test]
+    fn read_from_multiple_threads() {
+        // ANCHOR: read_from_multiple_threads
+        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        // ArrayFire Array's are internally maintained via atomic reference counting
+        // Thus, they need no Arc wrapping while moving to another thread.
+        // Just call clone method on the object and share the resulting clone object
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+                thread::spawn(move || {
+                    set_device(0); //Both of objects are created on device 0 earlier
+                    match op {
+                        Op::Add => {
+                            let _c = x + y;
+                        }
+                        Op::Sub => {
+                            let _c = x - y;
+                        }
+                        Op::Div => {
+                            let _c = x / y;
+                        }
+                        Op::Mul => {
+                            let _c = x * y;
+                        }
+                    }
+                    sync(0);
+                    thread::sleep(std::time::Duration::new(1, 0));
+                })
+            })
+            .collect();
+        for child in threads {
+            let _ = child.join();
+        }
+        // ANCHOR_END: read_from_multiple_threads
+    }
+
+    #[test]
+    fn access_using_rwlock() {
+        // ANCHOR: access_using_rwlock
+        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        // Move ownership to RwLock and wrap in Arc since same object is to be modified
+        let c_lock = Arc::new(RwLock::new(c));
+
+        // a and b are internally reference counted by ArrayFire. Unless there
+        // is prior known need that they may be modified, you can simply clone
+        // the objects pass them to threads
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                let x = a.clone();
+                let y = b.clone();
+
+                let wlock = c_lock.clone();
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+                    if let Ok(mut c_guard) = wlock.write() {
+                        match op {
+                            Op::Add => {
+                                *c_guard += x + y;
+                            }
+                            Op::Sub => {
+                                *c_guard += x - y;
+                            }
+                            Op::Div => {
+                                *c_guard += x / y;
+                            }
+                            Op::Mul => {
+                                *c_guard += x * y;
+                            }
+                        }
+                    }
+                })
+            })
+            .collect();
+
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //let read_guard = c_lock.read().unwrap();
+        //af_print!("C after threads joined", *read_guard);
+        //C after threads joined
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        // ANCHOR_END: access_using_rwlock
+    }
+
+    #[test]
+    fn accum_using_channel() {
+        // ANCHOR: accum_using_channel
+        let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div];
+        let ops_len: usize = ops.len();
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+
+        let mut c = constant(0.0f32, dim4!(3, 3));
+        let a = constant(1.0f32, dim4!(3, 3));
+        let b = constant(2.0f32, dim4!(3, 3));
+
+        let (tx, rx) = mpsc::channel();
+
+        let threads: Vec<_> = ops
+            .into_iter()
+            .map(|op| {
+                // a and b are internally reference counted by ArrayFire. Unless there
+                // is prior known need that they may be modified, you can simply clone
+                // the objects pass them to threads
+                let x = a.clone();
+                let y = b.clone();
+
+                let tx_clone = tx.clone();
+
+                thread::spawn(move || {
+                    //Both of objects are created on device 0 in main thread
+                    //Every thread needs to set the device that it is going to
+                    //work on. Note that all Array objects must have been created
+                    //on same device as of date this is written on.
+                    set_device(0);
+
+                    let c = match op {
+                        Op::Add => x + y,
+                        Op::Sub => x - y,
+                        Op::Div => x / y,
+                        Op::Mul => x * y,
+                    };
+                    tx_clone.send(c).unwrap();
+                })
+            })
+            .collect();
+
+        for _i in 0..ops_len {
+            c += rx.recv().unwrap();
+        }
+
+        //Need to join other threads as main thread holds arrayfire context
+        for child in threads {
+            let _ = child.join();
+        }
+
+        //af_print!("C after accumulating results", &c);
+        //[3 3 1 1]
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        //    8.0000     8.0000     8.0000
+        // ANCHOR_END: accum_using_channel
+    }
+
+    #[cfg(feature = "afserde")]
+    mod serde_tests {
+        use super::super::Array;
+        use crate::algorithm::sum_all;
+        use crate::randu;
+
+        #[test]
+        fn array_serde_json() {
+            let input = randu!(u8; 2, 2);
+            let serd = match serde_json::to_string(&input) {
+                Ok(serialized_str) => serialized_str,
+                Err(e) => e.to_string(),
+            };
+
+            let deserd: Array<u8> = serde_json::from_str(&serd).unwrap();
+
+            assert_eq!(sum_all(&(input - deserd)), (0u32, 0u32));
+        }
+
+        #[test]
+        fn array_serde_bincode() {
+            let input = randu!(u8; 2, 2);
+            let encoded = match bincode::serialize(&input) {
+                Ok(encoded) => encoded,
+                Err(_) => vec![],
+            };
+
+            let decoded: Array<u8> = bincode::deserialize(&encoded).unwrap();
+
+            assert_eq!(sum_all(&(input - decoded)), (0u32, 0u32));
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/backend.rs.html b/src/arrayfire/core/backend.rs.html new file mode 100644 index 000000000..e704420e3 --- /dev/null +++ b/src/arrayfire/core/backend.rs.html @@ -0,0 +1,159 @@ +backend.rs - source + + + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+
+use super::defines::{AfError, Backend};
+use super::error::HANDLE_ERROR;
+
+use libc::{c_int, c_uint};
+
+extern "C" {
+    fn af_set_backend(bknd: u8) -> c_int;
+    fn af_get_backend_count(num_backends: *mut c_uint) -> c_int;
+    fn af_get_available_backends(backends: *mut c_int) -> c_int;
+    fn af_get_active_backend(backend: *mut c_int) -> c_int;
+}
+
+/// Toggle backends between cuda, opencl or cpu
+///
+/// # Parameters
+///
+/// - `backend` to which to switch to
+pub fn set_backend(backend: Backend) {
+    unsafe {
+        let err_val = af_set_backend(backend as u8);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get the available backend count
+pub fn get_backend_count() -> u32 {
+    unsafe {
+        let mut temp: u32 = 0;
+        let err_val = af_get_backend_count(&mut temp as *mut c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp
+    }
+}
+
+/// Get the available backends
+pub fn get_available_backends() -> Vec<Backend> {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_available_backends(&mut temp as *mut c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+
+        let mut b = Vec::new();
+        if temp & 0b0100 == 0b0100 {
+            b.push(Backend::OPENCL);
+        }
+        if temp & 0b0010 == 0b0010 {
+            b.push(Backend::CUDA);
+        }
+        if temp & 0b0001 == 0b0001 {
+            b.push(Backend::CPU);
+        }
+
+        b
+    }
+}
+
+/// Get current active backend
+pub fn get_active_backend() -> Backend {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_active_backend(&mut temp as *mut c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        match (err_val, temp) {
+            (0, 0) => Backend::DEFAULT,
+            (0, 1) => Backend::CPU,
+            (0, 2) => Backend::CUDA,
+            (0, 4) => Backend::OPENCL,
+            _ => panic!("Invalid backend retrieved, undefined behavior."),
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/data.rs.html b/src/arrayfire/core/data.rs.html new file mode 100644 index 000000000..0c63e6588 --- /dev/null +++ b/src/arrayfire/core/data.rs.html @@ -0,0 +1,1997 @@ +data.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+
+use super::array::Array;
+use super::defines::{AfError, BorderType};
+use super::dim4::Dim4;
+use super::error::HANDLE_ERROR;
+use super::util::{af_array, c32, c64, dim_t, u64_t, HasAfEnum};
+
+use libc::{c_double, c_int, c_uint};
+use std::option::Option;
+use std::vec::Vec;
+
+extern "C" {
+    fn af_constant(
+        out: *mut af_array,
+        val: c_double,
+        ndims: c_uint,
+        dims: *const dim_t,
+        afdtype: c_uint,
+    ) -> c_int;
+
+    fn af_constant_complex(
+        out: *mut af_array,
+        real: c_double,
+        imag: c_double,
+        ndims: c_uint,
+        dims: *const dim_t,
+        afdtype: c_uint,
+    ) -> c_int;
+
+    fn af_constant_long(out: *mut af_array, val: dim_t, ndims: c_uint, dims: *const dim_t)
+        -> c_int;
+
+    fn af_constant_ulong(
+        out: *mut af_array,
+        val: u64_t,
+        ndims: c_uint,
+        dims: *const dim_t,
+    ) -> c_int;
+
+    fn af_range(
+        out: *mut af_array,
+        ndims: c_uint,
+        dims: *const dim_t,
+        seq_dim: c_int,
+        afdtype: c_uint,
+    ) -> c_int;
+
+    fn af_iota(
+        out: *mut af_array,
+        ndims: c_uint,
+        dims: *const dim_t,
+        t_ndims: c_uint,
+        tdims: *const dim_t,
+        afdtype: c_uint,
+    ) -> c_int;
+
+    fn af_identity(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint)
+        -> c_int;
+    fn af_diag_create(out: *mut af_array, arr: af_array, num: c_int) -> c_int;
+    fn af_diag_extract(out: *mut af_array, arr: af_array, num: c_int) -> c_int;
+    fn af_join(out: *mut af_array, dim: c_int, first: af_array, second: af_array) -> c_int;
+    fn af_join_many(
+        out: *mut af_array,
+        dim: c_int,
+        n_arrays: c_uint,
+        inpts: *const af_array,
+    ) -> c_int;
+
+    fn af_tile(
+        out: *mut af_array,
+        arr: af_array,
+        x: c_uint,
+        y: c_uint,
+        z: c_uint,
+        w: c_uint,
+    ) -> c_int;
+    fn af_reorder(
+        o: *mut af_array,
+        a: af_array,
+        x: c_uint,
+        y: c_uint,
+        z: c_uint,
+        w: c_uint,
+    ) -> c_int;
+    fn af_shift(o: *mut af_array, a: af_array, x: c_int, y: c_int, z: c_int, w: c_int) -> c_int;
+    fn af_moddims(out: *mut af_array, arr: af_array, ndims: c_uint, dims: *const dim_t) -> c_int;
+
+    fn af_flat(out: *mut af_array, arr: af_array) -> c_int;
+    fn af_flip(out: *mut af_array, arr: af_array, dim: c_uint) -> c_int;
+    fn af_lower(out: *mut af_array, arr: af_array, is_unit_diag: bool) -> c_int;
+    fn af_upper(out: *mut af_array, arr: af_array, is_unit_diag: bool) -> c_int;
+
+    fn af_select(out: *mut af_array, cond: af_array, a: af_array, b: af_array) -> c_int;
+    fn af_select_scalar_l(out: *mut af_array, cond: af_array, a: c_double, b: af_array) -> c_int;
+    fn af_select_scalar_r(out: *mut af_array, cond: af_array, a: af_array, b: c_double) -> c_int;
+
+    fn af_replace(a: *mut af_array, cond: af_array, b: af_array) -> c_int;
+    fn af_replace_scalar(a: *mut af_array, cond: af_array, b: c_double) -> c_int;
+
+    fn af_pad(
+        out: *mut af_array,
+        input: af_array,
+        begin_ndims: c_uint,
+        begin_dims: *const dim_t,
+        end_ndims: c_uint,
+        end_dims: *const dim_t,
+        pad_fill_type: c_uint,
+    ) -> c_int;
+}
+
+/// Type Trait to generate a constant [Array](./struct.Array.html) of given size
+///
+/// Internally, ConstGenerator trait is implemented by following types.
+///
+/// - f32
+/// - f64
+/// - num::Complex\<f32\>
+/// - num::Complex\<f64\>
+/// - bool
+/// - i32
+/// - u32
+/// - u8
+/// - i64
+/// - u64
+/// - i16
+/// - u16
+///
+pub trait ConstGenerator: HasAfEnum {
+    /// The type of Array<T> object returned by generate function
+    type OutType: HasAfEnum;
+
+    /// Create an Array of `dims` size from scalar value `self`.
+    ///
+    /// # Parameters
+    ///
+    /// - `dims` are the dimensions of the output constant [Array](./struct.Array.html)
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType>;
+}
+
+impl ConstGenerator for i64 {
+    type OutType = i64;
+
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_constant_long(
+                &mut temp as *mut af_array,
+                *self,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+impl ConstGenerator for u64 {
+    type OutType = u64;
+
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_constant_ulong(
+                &mut temp as *mut af_array,
+                *self,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+impl ConstGenerator for c32 {
+    type OutType = c32;
+
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_constant_complex(
+                &mut temp as *mut af_array,
+                (*self).re as c_double,
+                (*self).im as c_double,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+                1,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+impl ConstGenerator for c64 {
+    type OutType = c64;
+
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_constant_complex(
+                &mut temp as *mut af_array,
+                (*self).re as c_double,
+                (*self).im as c_double,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+                3,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+impl ConstGenerator for bool {
+    type OutType = bool;
+
+    fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+        unsafe {
+            let mut temp: af_array = std::ptr::null_mut();
+            let err_val = af_constant(
+                &mut temp as *mut af_array,
+                *self as c_int as c_double,
+                dims.ndims() as c_uint,
+                dims.get().as_ptr() as *const dim_t,
+                4,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            temp.into()
+        }
+    }
+}
+
+macro_rules! cnst {
+    ($rust_type:ty, $ffi_type:expr) => {
+        impl ConstGenerator for $rust_type {
+            type OutType = $rust_type;
+
+            fn generate(&self, dims: Dim4) -> Array<Self::OutType> {
+                unsafe {
+                    let mut temp: af_array = std::ptr::null_mut();
+                    let err_val = af_constant(
+                        &mut temp as *mut af_array,
+                        *self as c_double,
+                        dims.ndims() as c_uint,
+                        dims.get().as_ptr() as *const dim_t,
+                        $ffi_type,
+                    );
+                    HANDLE_ERROR(AfError::from(err_val));
+                    temp.into()
+                }
+            }
+        }
+    };
+}
+
+cnst!(f32, 0);
+cnst!(f64, 2);
+cnst!(i32, 5);
+cnst!(u32, 6);
+cnst!(u8, 7);
+cnst!(i16, 10);
+cnst!(u16, 11);
+
+/// Create an Array with constant value
+///
+/// The trait ConstGenerator has been defined internally for the following types:
+///
+/// - i64
+/// - u64
+/// - num::Complex\<f32\> a.k.a c32
+/// - num::Complex\<f64\> a.k.a c64
+/// - f32
+/// - f64
+/// - i32
+/// - u32
+/// - u8
+/// - i16
+/// - u16
+///
+/// # Parameters
+///
+/// - `cnst` is the constant value to be filled in the Array
+/// - `dims` is the size of the constant Array
+///
+/// # Return Values
+///
+/// An Array of given dimensions with constant value
+pub fn constant<T>(cnst: T, dims: Dim4) -> Array<T>
+where
+    T: ConstGenerator<OutType = T>,
+{
+    cnst.generate(dims)
+}
+
+/// Create a Range of values
+///
+/// Creates an array with [0, n] values along the `seq_dim` which is tiled across other dimensions.
+///
+/// # Parameters
+///
+/// - `dims` is the size of Array
+/// - `seq_dim` is the dimension along which range values are populated, all values along other
+/// dimensions are just repeated
+///
+/// # Return Values
+/// Array
+pub fn range<T: HasAfEnum>(dims: Dim4, seq_dim: i32) -> Array<T> {
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_range(
+            &mut temp as *mut af_array,
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+            seq_dim as c_int,
+            aftype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create a range of values
+///
+/// Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims.
+///
+/// # Parameters
+///
+/// - `dims` is the dimensions of the sequence to be generated
+/// - `tdims` is the number of repitions of the unit dimensions
+///
+/// # Return Values
+///
+/// Array
+pub fn iota<T: HasAfEnum>(dims: Dim4, tdims: Dim4) -> Array<T> {
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_iota(
+            &mut temp as *mut af_array,
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+            tdims.ndims() as c_uint,
+            tdims.get().as_ptr() as *const dim_t,
+            aftype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create an identity array with 1's in diagonal
+///
+/// # Parameters
+///
+/// - `dims` is the output Array dimensions
+///
+/// # Return Values
+///
+/// Identity matrix
+pub fn identity<T: HasAfEnum>(dims: Dim4) -> Array<T> {
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_identity(
+            &mut temp as *mut af_array,
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+            aftype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create a diagonal matrix
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `dim` is the diagonal index relative to principal diagonal where values from input Array are
+/// to be placed
+///
+/// # Return Values
+///
+/// An Array with values as a diagonal Matrix
+pub fn diag_create<T>(input: &Array<T>, dim: i32) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_diag_create(&mut temp as *mut af_array, input.get(), dim);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Extract diagonal from a given Matrix
+///
+/// # Parameters
+///
+/// - `input` is the input Matrix
+/// - `dim` is the index of the diagonal that has to be extracted from the input Matrix
+///
+/// # Return Values
+///
+/// An Array with values of the diagonal from input Array
+pub fn diag_extract<T>(input: &Array<T>, dim: i32) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_diag_extract(&mut temp as *mut af_array, input.get(), dim);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Join two arrays
+///
+/// # Parameters
+///
+/// - `dim` is the dimension along which the concatenation has to be done
+/// - `first` is the Array that comes first in the concatenation
+/// - `second` is the Array that comes last in the concatenation
+///
+/// # Return Values
+///
+/// Concatenated Array
+pub fn join<T>(dim: i32, first: &Array<T>, second: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_join(&mut temp as *mut af_array, dim, first.get(), second.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Join multiple arrays
+///
+/// # Parameters
+///
+/// - `dim` is the dimension along which the concatenation has to be done
+/// - `inputs` is the vector of Arrays that has to be concatenated
+///
+/// # Return Values
+///
+/// Concatenated Array
+pub fn join_many<T>(dim: i32, inputs: Vec<&Array<T>>) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut v = Vec::new();
+        for i in inputs {
+            v.push(i.get());
+        }
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_join_many(
+            &mut temp as *mut af_array,
+            dim,
+            v.len() as u32,
+            v.as_ptr() as *const af_array,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Tile the input array along specified dimension
+///
+/// Tile essentially creates copies of data along each dimension.
+/// The number of copies created is provided by the user on per
+/// axis basis using [Dim4](./struct.dim4.html)
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `dims` is the target(output) dimensions
+///
+///# Return Values
+///
+/// Tiled input array as per the tiling dimensions provided
+pub fn tile<T>(input: &Array<T>, dims: Dim4) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_tile(
+            &mut temp as *mut af_array,
+            input.get() as af_array,
+            dims[0] as c_uint,
+            dims[1] as c_uint,
+            dims[2] as c_uint,
+            dims[3] as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Reorder the array according to the new specified axes
+///
+/// Exchanges data within an array such that the requested change in axes is
+/// satisfied. The linear ordering of data within the array is preserved.
+///
+/// The default order of axes in ArrayFire is [0 1 2 3] i.e. axis with smallest
+/// distance between adjacent elements followed by next smallest distance axis and
+/// so on. See [examples](#examples) to have a basic idea of how data is re-ordered.
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `new_axis0` is the new first axis for output
+/// - `new_axis1` is the new second axis for output
+/// - `next_axes` is the new axes order for output
+///
+///# Return Values
+///
+/// Array with data reordered as per the new axes order
+///
+///# Examples
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, print, randu, reorder_v2};
+/// let a  = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// let b  = reorder_v2(&a, 1, 0, None);
+/// print(&a);
+///
+/// // [5 3 1 1]
+/// //  0.8104     0.2990     0.3014
+/// //  0.6913     0.2802     0.6938
+/// //  0.7821     0.1480     0.3513
+/// //  0.3054     0.1330     0.7176
+/// //  0.1673     0.4696     0.1181
+///
+/// print(&b);
+/// // [3 5 1 1]
+/// //     0.8104     0.6913     0.7821     0.3054     0.1673
+/// //     0.2990     0.2802     0.1480     0.1330     0.4696
+/// //     0.3014     0.6938     0.3513     0.7176     0.1181
+///
+/// let c  = reorder_v2(&a, 2, 0, Some(vec![1]));
+/// print(&c);
+///
+/// // [1 5 3 1]
+/// //  0.8104     0.6913     0.7821     0.3054     0.1673
+/// //
+/// //  0.2990     0.2802     0.1480     0.1330     0.4696
+/// //
+/// //  0.3014     0.6938     0.3513     0.7176     0.1181
+/// ```
+pub fn reorder_v2<T>(
+    input: &Array<T>,
+    new_axis0: u64,
+    new_axis1: u64,
+    next_axes: Option<Vec<u64>>,
+) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let mut new_axes = [0, 1, 2, 3];
+    new_axes[0] = new_axis0;
+    new_axes[1] = new_axis1;
+    match next_axes {
+        Some(left_over_new_axes) => {
+            // At the moment of writing this comment, ArrayFire could
+            // handle only a maximum of 4 dimensions. Hence, excluding
+            // the two explicit axes arguments to this function, a maximum
+            // of only two more axes can be provided. Hence the below condition.
+            assert!(left_over_new_axes.len() <= 2);
+
+            for a_idx in 0..left_over_new_axes.len() {
+                new_axes[2 + a_idx] = left_over_new_axes[a_idx];
+            }
+        }
+        None => {
+            for a_idx in 2..4 {
+                new_axes[a_idx] = a_idx as u64;
+            }
+        }
+    };
+
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_reorder(
+            &mut temp as *mut af_array,
+            input.get() as af_array,
+            new_axes[0] as c_uint,
+            new_axes[1] as c_uint,
+            new_axes[2] as c_uint,
+            new_axes[3] as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Reorder the array in specified order
+///
+/// The default order of axes in ArrayFire is axis with smallest distance
+/// between adjacent elements towards an axis with highest distance between
+/// adjacent elements.
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `dims` is the target(output) dimensions
+///
+///# Return Values
+///
+/// Array with data reordered as per the new axes order
+#[deprecated(since = "3.6.3", note = "Please use new reorder API")]
+pub fn reorder<T>(input: &Array<T>, dims: Dim4) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    reorder_v2(input, dims[0], dims[1], Some(vec![dims[2], dims[3]]))
+}
+
+///"Circular shift of values along specified dimension
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `offsets` is 4-value tuple that specifies the shift along respective dimension
+///
+///# Return Values
+///
+/// An Array with shifted data.
+///
+///# Examples
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, print, randu, shift};
+/// let a  = randu::<f32>(Dim4::new(&[5, 1, 1, 1]));
+/// let _a = shift(&a, &[-1i32, 1 , 1, 1]); //shift data one step backward
+/// let a_ = shift(&a, &[ 1i32, 1 , 1, 1]); //shift data one step forward
+/// print(& a);
+/// print(&_a);
+/// print(&a_);
+/// ```
+pub fn shift<T>(input: &Array<T>, offsets: &[i32; 4]) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_shift(
+            &mut temp as *mut af_array,
+            input.get(),
+            offsets[0],
+            offsets[1],
+            offsets[2],
+            offsets[3],
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Change the shape of the Array
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `dims` is the new dimensions to which the input Array is reshaped to
+///
+/// # Return Values
+/// Reshaped Array
+pub fn moddims<T>(input: &Array<T>, dims: Dim4) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_moddims(
+            &mut temp as *mut af_array,
+            input.get(),
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Flatten the multidimensional Array to an 1D Array
+pub fn flat<T>(input: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_flat(&mut temp as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Flip the Array
+///
+/// # Parameters
+///
+/// - `input` is the Array to be flipped
+/// - `dim` is the dimension along which the flip has to happen
+///
+/// # Return Values
+///
+/// Flipped Array
+pub fn flip<T>(input: &Array<T>, dim: u32) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_flip(&mut temp as *mut af_array, input.get(), dim);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create lower triangular matrix
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `is_unit_diag` dictates if the output Array should have 1's along diagonal
+///
+/// # Return Values
+/// Array
+pub fn lower<T>(input: &Array<T>, is_unit_diag: bool) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_lower(&mut temp as *mut af_array, input.get(), is_unit_diag);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create upper triangular matrix
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `is_unit_diag` dictates if the output Array should have 1's along diagonal
+///
+/// # Return Values
+/// Array
+pub fn upper<T>(input: &Array<T>, is_unit_diag: bool) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_upper(&mut temp as *mut af_array, input.get(), is_unit_diag);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Element wise conditional operator for Arrays
+///
+/// This function does the C-equivalent of the following statement, except that the operation
+/// happens on a GPU for all elements simultaneously.
+///
+/// ```text
+/// c = cond ? a : b; /// where cond, a & b are all objects of type Array
+/// ```
+///
+/// # Parameters
+///
+/// - `a` is the Array whose element will be assigned to output if corresponding element in `cond` Array is
+/// `True`
+/// - `cond` is the Array with boolean values
+/// - `b` is the Array whose element will be assigned to output if corresponding element in `cond` Array is
+/// `False`
+///
+/// # Return Values
+///
+/// An Array
+pub fn select<T>(a: &Array<T>, cond: &Array<bool>, b: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_select(&mut temp as *mut af_array, cond.get(), a.get(), b.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Element wise conditional operator for Arrays
+///
+/// This function does the C-equivalent of the following statement, except that the operation
+/// happens on a GPU for all elements simultaneously.
+///
+/// ```text
+/// c = cond ? a : b; /// where  a is a scalar(f64) and b is Array
+/// ```
+///
+/// # Parameters
+///
+/// - `a` is the scalar that is assigned to output if corresponding element in `cond` Array is
+/// `True`
+/// - `cond` is the Array with conditional values
+/// - `b` is the Array whose element will be assigned to output if corresponding element in `cond` Array is
+/// `False`
+///
+/// # Return Values
+///
+/// An Array
+pub fn selectl<T>(a: f64, cond: &Array<bool>, b: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_select_scalar_l(&mut temp as *mut af_array, cond.get(), a, b.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Element wise conditional operator for Arrays
+///
+/// This function does the C-equivalent of the following statement, except that the operation
+/// happens on a GPU for all elements simultaneously.
+///
+/// ```text
+/// c = cond ? a : b; /// where a is Array and b is a scalar(f64)
+/// ```
+///
+/// # Parameters
+///
+/// - `a` is the Array whose element will be assigned to output if corresponding element in `cond` Array is
+/// `True`
+/// - `cond` is the Array with conditional values
+/// - `b` is the scalar that is assigned to output if corresponding element in `cond` Array is
+/// `False`
+///
+/// # Return Values
+///
+/// An Array
+pub fn selectr<T>(a: &Array<T>, cond: &Array<bool>, b: f64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_select_scalar_r(&mut temp as *mut af_array, cond.get(), a.get(), b);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inplace replace in Array based on a condition
+///
+/// This function does the C-equivalent of the following statement, except that the operation
+/// happens on a GPU for all elements simultaneously.
+///
+/// ```text
+/// a = cond ? a : b; /// where cond, a & b are all objects of type Array
+/// ```
+///
+/// # Parameters
+///
+/// - `a` is the Array whose element will be replaced with element from `b` if corresponding element in `cond` Array is `True`
+/// - `cond` is the Array with conditional values
+/// - `b` is the Array whose element will replace the element in output if corresponding element in `cond` Array is
+/// `False`
+///
+/// # Return Values
+///
+/// None
+pub fn replace<T>(a: &mut Array<T>, cond: &Array<bool>, b: &Array<T>)
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let err_val = af_replace(a.get() as *mut af_array, cond.get(), b.get());
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Inplace replace in Array based on a condition
+///
+/// This function does the C-equivalent of the following statement, except that the operation
+/// happens on a GPU for all elements simultaneously.
+///
+/// ```text
+/// a = cond ? a : b; /// where cond, a are Arrays and b is scalar(f64)
+/// ```
+///
+/// # Parameters
+///
+/// - `a` is the Array whose element will be replaced with element from `b` if corresponding element in `cond` Array is `True`
+/// - `cond` is the Array with conditional values
+/// - `b` is the scalar that will replace the element in output if corresponding element in `cond` Array is
+/// `False`
+///
+/// # Return Values
+///
+/// None
+pub fn replace_scalar<T>(a: &mut Array<T>, cond: &Array<bool>, b: f64)
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let err_val = af_replace_scalar(a.get() as *mut af_array, cond.get(), b);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Pad input Array along borders
+///
+/// # Parameters
+///
+/// - `input` is the input array to be padded
+/// - `begin` is padding size before first element along a given dimension
+/// - `end` is padding size after the last element along a given dimension
+/// - `fill_type` indicates what values should be used to fill padded regions
+///
+/// # Return Values
+///
+/// Padded Array
+pub fn pad<T: HasAfEnum>(
+    input: &Array<T>,
+    begin: Dim4,
+    end: Dim4,
+    fill_type: BorderType,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_pad(
+            &mut temp as *mut af_array,
+            input.get(),
+            4,
+            begin.get().as_ptr() as *const dim_t,
+            4,
+            end.get().as_ptr() as *const dim_t,
+            fill_type as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::reorder_v2;
+
+    use super::super::defines::BorderType;
+    use super::super::device::set_device;
+    use super::super::random::randu;
+    use super::pad;
+
+    use crate::dim4;
+
+    #[test]
+    fn check_reorder_api() {
+        set_device(0);
+        let a = randu::<f32>(dim4!(4, 5, 2, 3));
+
+        let _transposed = reorder_v2(&a, 1, 0, None);
+        let _swap_0_2 = reorder_v2(&a, 2, 1, Some(vec![0]));
+        let _swap_1_2 = reorder_v2(&a, 0, 2, Some(vec![1]));
+        let _swap_0_3 = reorder_v2(&a, 3, 1, Some(vec![2, 0]));
+    }
+
+    #[test]
+    fn check_pad_api() {
+        set_device(0);
+        let a = randu::<f32>(dim4![3, 3]);
+        let begin_dims = dim4!(0, 0, 0, 0);
+        let end_dims = dim4!(2, 2, 0, 0);
+        let _padded = pad(&a, begin_dims, end_dims, BorderType::ZERO);
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/defines.rs.html b/src/arrayfire/core/defines.rs.html new file mode 100644 index 000000000..182b25bca --- /dev/null +++ b/src/arrayfire/core/defines.rs.html @@ -0,0 +1,1297 @@ +defines.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+
+use num::Complex;
+use std::fmt::Error as FmtError;
+use std::fmt::{Display, Formatter};
+
+#[cfg(feature = "afserde")]
+use serde::{Deserialize, Serialize};
+
+/// Error codes
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum AfError {
+    /// The function returned successfully
+    SUCCESS = 0,
+    // 100-199 Errors in environment
+    /// The system or device ran out of memory
+    ERR_NO_MEM = 101,
+    /// There was an error in the device driver
+    ERR_DRIVER = 102,
+    /// There was an error with the runtime environment
+    ERR_RUNTIME = 103,
+    // 200-299 Errors in input parameters
+    /// The input array is not a valid Array object
+    ERR_INVALID_ARRAY = 201,
+    /// One of the function arguments is incorrect
+    ERR_ARG = 202,
+    /// The size is incorrect
+    ERR_SIZE = 203,
+    /// The type is not suppported by this function
+    ERR_TYPE = 204,
+    /// The type of the input arrays are not compatible
+    ERR_DIFF_TYPE = 205,
+    /// Function does not support GFOR / batch mode
+    ERR_BATCH = 207,
+    /// Input does not belong to the current device
+    ERR_DEVICE = 208,
+    // 300-399 Errors for missing software features
+    /// The option is not supported
+    ERR_NOT_SUPPORTED = 301,
+    /// This build of ArrayFire does not support this feature
+    ERR_NOT_CONFIGURED = 302,
+    // 400-499 Errors for missing hardware features
+    /// This device does not support double
+    ERR_NO_DBL = 401,
+    /// This build of ArrayFire was not built with graphics or this device does
+    /// not support graphics
+    ERR_NO_GFX = 402,
+    // 900-999 Errors from upstream libraries and runtimes
+    /// There was an internal error either in ArrayFire or in a project
+    /// upstream
+    ERR_INTERNAL = 998,
+    /// Unknown Error
+    ERR_UNKNOWN = 999,
+}
+
+/// Compute/Acceleration Backend
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum Backend {
+    /// Default backend order: OpenCL -> CUDA -> CPU
+    DEFAULT = 0,
+    /// CPU a.k.a sequential algorithms
+    CPU = 1,
+    /// CUDA Compute Backend
+    CUDA = 2,
+    /// OpenCL Compute Backend
+    OPENCL = 4,
+}
+
+impl Display for Backend {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
+        let text = match *self {
+            Backend::OPENCL => "OpenCL",
+            Backend::CUDA => "Cuda",
+            Backend::CPU => "CPU",
+            Backend::DEFAULT => "Default",
+        };
+        write!(f, "{}", text)
+    }
+}
+
+impl Display for AfError {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
+        let text = match *self {
+            AfError::SUCCESS => "Function returned successfully",
+            AfError::ERR_NO_MEM => "System or Device ran out of memory",
+            AfError::ERR_DRIVER => "Error in the device driver",
+            AfError::ERR_RUNTIME => "Error with the runtime environment",
+            AfError::ERR_INVALID_ARRAY => "Iput Array is not a valid object",
+            AfError::ERR_ARG => "One of the function arguments is incorrect",
+            AfError::ERR_SIZE => "Size is incorrect",
+            AfError::ERR_TYPE => "Type is not suppported by this function",
+            AfError::ERR_DIFF_TYPE => "Type of the input arrays are not compatible",
+            AfError::ERR_BATCH => "Function does not support GFOR / batch mode",
+            AfError::ERR_DEVICE => "Input does not belong to the current device",
+            AfError::ERR_NOT_SUPPORTED => "Unsupported operation/parameter option",
+            AfError::ERR_NOT_CONFIGURED => "This build of ArrayFire does not support this feature",
+            AfError::ERR_NO_DBL => "This device does not support double",
+            AfError::ERR_NO_GFX => "This build of ArrayFire has no graphics support",
+            AfError::ERR_INTERNAL => "Error either in ArrayFire or in a project upstream",
+            AfError::ERR_UNKNOWN => "Unknown Error",
+        };
+        write!(f, "{}", text)
+    }
+}
+
+/// Types of Array data type
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum DType {
+    /// 32 bit float
+    F32 = 0,
+    /// 32 bit complex float
+    C32 = 1,
+    /// 64 bit float
+    F64 = 2,
+    /// 64 bit complex float
+    C64 = 3,
+    /// 8 bit boolean
+    B8 = 4,
+    /// 32 bit signed integer
+    S32 = 5,
+    /// 32 bit unsigned integer
+    U32 = 6,
+    /// 8 bit unsigned integer
+    U8 = 7,
+    /// 64 bit signed integer
+    S64 = 8,
+    /// 64 bit unsigned integer
+    U64 = 9,
+    /// 16 bit signed integer
+    S16 = 10,
+    /// 16 bit unsigned integer
+    U16 = 11,
+    /// 16 bit floating point
+    F16 = 12,
+}
+
+/// Dictates the interpolation method to be used by a function
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum InterpType {
+    /// Nearest Neighbor interpolation method
+    NEAREST = 0,
+    /// Linear interpolation method
+    LINEAR = 1,
+    /// Bilinear interpolation method
+    BILINEAR = 2,
+    /// Cubic interpolation method
+    CUBIC = 3,
+    /// Floor indexed
+    LOWER = 4,
+    /// Linear interpolation with cosine smoothing
+    LINEAR_COSINE = 5,
+    /// Bilinear interpolation with cosine smoothing
+    BILINEAR_COSINE = 6,
+    /// Bicubic interpolation
+    BICUBIC = 7,
+    /// Cubic interpolation with Catmull-Rom splines
+    CUBIC_SPLINE = 8,
+    /// Bicubic interpolation with Catmull-Rom splines
+    BICUBIC_SPLINE = 9,
+}
+
+/// Helps determine how to pad kernels along borders
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum BorderType {
+    /// Pad using zeros
+    ZERO = 0,
+    /// Pad using mirrored values along border
+    SYMMETRIC = 1,
+
+    /// Out of bound values are clamped to the edge
+    CLAMP_TO_EDGE,
+
+    /// Out of bound values are mapped to range of the dimension in cyclic fashion
+    PERIODIC,
+}
+
+/// Used by `regions` function to identify type of connectivity
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum Connectivity {
+    /// North-East-South-West (N-E-S-W) connectivity from given pixel/point
+    FOUR = 4,
+    /// N-NE-E-SE-S-SW-W-NW connectivity from given pixel/point
+    EIGHT = 8,
+}
+
+/// Helps determine the size of output of convolution
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum ConvMode {
+    /// Default convolution mode where output size is same as input size
+    DEFAULT = 0,
+    /// Output of convolution is expanded based on signal and filter sizes
+    EXPAND = 1,
+}
+
+/// Helps determine if convolution is in Spatial or Frequency domain
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum ConvDomain {
+    /// ArrayFire chooses whether the convolution will be in spatial domain or frequency domain
+    AUTO = 0,
+    /// Convoltion in spatial domain
+    SPATIAL = 1,
+    /// Convolution in frequency domain
+    FREQUENCY = 2,
+}
+
+/// Error metric used by `matchTemplate` function
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum MatchType {
+    /// Sum of Absolute Differences
+    SAD = 0,
+    /// Zero-mean Sum of Absolute Differences
+    ZSAD = 1,
+    /// Locally scaled Sum of Absolute Differences
+    LSAD = 2,
+    /// Sum of Squared Differences
+    SSD = 3,
+    /// Zero-mean Sum of Squared Differences
+    ZSSD = 4,
+    /// Localy scaled Sum of Squared Differences
+    LSSD = 5,
+    /// Normalized Cross Correlation
+    NCC = 6,
+    /// Zero-mean Normalized Cross Correlation
+    ZNCC = 7,
+    /// Sum of Hamming Distances
+    SHD = 8,
+}
+
+/// Identify the color space of given image(Array)
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum ColorSpace {
+    /// Grayscale color space
+    GRAY = 0,
+    /// Red-Green-Blue color space
+    RGB = 1,
+    /// Hue-Saturation-value color space
+    HSV = 2,
+}
+
+/// Helps determine the type of a Matrix
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum MatProp {
+    /// Default (no-op)
+    NONE = 0,
+    /// Data needs to be transposed
+    TRANS = 1,
+    /// Data needs to be conjugate transposed
+    CTRANS = 2,
+    /// Matrix is upper triangular
+    CONJ = 4,
+    /// Matrix needs to be conjugate
+    UPPER = 32,
+    /// Matrix is lower triangular
+    LOWER = 64,
+    /// Matrix diagonal has unitary values
+    DIAGUNIT = 128,
+    /// Matrix is symmetric
+    SYM = 512,
+    /// Matrix is positive definite
+    POSDEF = 1024,
+    /// Matrix is orthogonal
+    ORTHOG = 2048,
+    /// Matrix is tri-diagonal
+    TRIDIAG = 4096,
+    /// Matrix is block-diagonal
+    BLOCKDIAG = 8192,
+}
+
+/// Norm type
+#[allow(non_camel_case_types)]
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum NormType {
+    /// Treats input as a vector and return sum of absolute values
+    VECTOR_1 = 0,
+    /// Treats input as vector and return max of absolute values
+    VECTOR_INF = 1,
+    /// Treats input as vector and returns euclidean norm
+    VECTOR_2 = 2,
+    /// Treats input as vector and returns the p-norm
+    VECTOR_P = 3,
+    /// Return the max of column sums
+    MATRIX_1 = 4,
+    /// Return the max of row sums
+    MATRIX_INF = 5,
+    /// Returns the max singular value (Currently not supported)
+    MATRIX_2 = 6,
+    /// Returns Lpq-norm
+    MATRIX_L_PQ = 7,
+}
+
+/// Dictates what color map is used for Image rendering
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum ColorMap {
+    /// Default color map is grayscale range [0-1]
+    DEFAULT = 0,
+    /// Visible spectrum color map
+    SPECTRUM = 1,
+    /// Colors
+    COLORS = 2,
+    /// Red hue map
+    RED = 3,
+    /// Mood color map
+    MOOD = 4,
+    /// Heat color map
+    HEAT = 5,
+    /// Blue hue map
+    BLUE = 6,
+}
+
+/// YCbCr Standards
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum YCCStd {
+    /// ITU-R BT.601 (formerly CCIR 601) standard
+    YCC_601 = 601,
+    /// ITU-R BT.709 standard
+    YCC_709 = 709,
+    /// ITU-R BT.2020 standard
+    YCC_2020 = 2020,
+}
+
+/// Homography type
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum HomographyType {
+    /// RANdom SAmple Consensus algorithm
+    RANSAC = 0,
+    /// Least Median of Squares
+    LMEDS = 1,
+}
+
+/// Plotting markers
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum MarkerType {
+    /// No marker
+    NONE = 0,
+    /// Pointer marker
+    POINT = 1,
+    /// Hollow circle marker
+    CIRCLE = 2,
+    /// Hollow Square marker
+    SQUARE = 3,
+    /// Hollow Triangle marker
+    TRIANGLE = 4,
+    /// Cross-hair marker
+    CROSS = 5,
+    /// Plus symbol marker
+    PLUS = 6,
+    /// Start symbol marker
+    STAR = 7,
+}
+
+/// Image moment types
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum MomentType {
+    /// Central moment of order (0 + 0)
+    M00 = 1, // 1<<0
+    /// Central moment of order (0 + 1)
+    M01 = 2, // 1<<1
+    /// Central moment of order (1 + 0)
+    M10 = 4, // 1<<2
+    /// Central moment of order (1 + 1)
+    M11 = 8, // 1<<3
+    /// All central moments of order (0,0), (0,1), (1,0) and (1,1)
+    FIRST_ORDER = 1 | 1 << 1 | 1 << 2 | 1 << 3,
+}
+
+/// Sparse storage format type
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum SparseFormat {
+    /// Dense format
+    DENSE = 0,
+    /// Compressed sparse row format
+    CSR = 1,
+    /// Compressed sparse coloumn format
+    CSC = 2,
+    /// Coordinate list (row, coloumn, value) tuples.
+    COO = 3,
+}
+
+/// Binary operation types for generalized scan functions
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum BinaryOp {
+    /// Addition operation
+    ADD = 0,
+    /// Multiplication operation
+    MUL = 1,
+    /// Minimum operation
+    MIN = 2,
+    /// Maximum operation
+    MAX = 3,
+}
+
+/// Random engine types
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum RandomEngineType {
+    ///Philox variant with N=4, W=32 and Rounds=10
+    PHILOX_4X32_10 = 100,
+    ///Threefry variant with N=2, W=32 and Rounds=16
+    THREEFRY_2X32_16 = 200,
+    ///Mersenne variant with MEXP = 11213
+    MERSENNE_GP11213 = 300,
+}
+
+/// Default Philon RandomEngine that points to [PHILOX_4X32_10](./enum.RandomEngineType.html)
+pub const PHILOX: RandomEngineType = RandomEngineType::PHILOX_4X32_10;
+/// Default Threefry RandomEngine that points to [THREEFRY_2X32_16](./enum.RandomEngineType.html)
+pub const THREEFRY: RandomEngineType = RandomEngineType::THREEFRY_2X32_16;
+/// Default Mersenne RandomEngine that points to [MERSENNE_GP11213](./enum.RandomEngineType.html)
+pub const MERSENNE: RandomEngineType = RandomEngineType::MERSENNE_GP11213;
+/// Default RandomEngine that defaults to [PHILOX](./constant.PHILOX.html)
+pub const DEFAULT_RANDOM_ENGINE: RandomEngineType = PHILOX;
+
+#[cfg(feature = "afserde")]
+#[derive(Serialize, Deserialize)]
+#[serde(remote = "Complex")]
+struct ComplexDef<T> {
+    re: T,
+    im: T,
+}
+
+/// Scalar value types
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum Scalar {
+    /// 32 bit float
+    F32(f32),
+    /// 32 bit complex float
+    #[cfg_attr(feature = "afserde", serde(with = "ComplexDef"))]
+    C32(Complex<f32>),
+    /// 64 bit float
+    F64(f64),
+    /// 64 bit complex float
+    #[cfg_attr(feature = "afserde", serde(with = "ComplexDef"))]
+    C64(Complex<f64>),
+    /// 8 bit boolean
+    B8(bool),
+    /// 32 bit signed integer
+    S32(i32),
+    /// 32 bit unsigned integer
+    U32(u32),
+    /// 8 bit unsigned integer
+    U8(u8),
+    /// 64 bit signed integer
+    S64(i64),
+    /// 64 bit unsigned integer
+    U64(u64),
+    /// 16 bit signed integer
+    S16(i16),
+    /// 16 bit unsigned integer
+    U16(u16),
+}
+
+/// Canny edge detector threshold operations types
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum CannyThresholdType {
+    /// User has to define canny thresholds manually
+    MANUAL = 0,
+    /// Determine canny algorithm high threshold using Otsu algorithm automatically
+    OTSU = 1,
+}
+
+/// Anisotropic diffusion flux equation types
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum DiffusionEq {
+    /// Quadratic flux function
+    QUADRATIC = 1,
+    /// Exponential flux function
+    EXPONENTIAL = 2,
+    /// Default flux function, a.k.a exponential
+    DEFAULT = 0,
+}
+
+/// Diffusion equation types
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum FluxFn {
+    /// Quadratic flux function
+    GRADIENT = 1,
+    /// Modified curvature diffusion equation
+    MCDE = 2,
+    /// Default diffusion method, Gradient
+    DEFAULT = 0,
+}
+
+/// topk function ordering
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum TopkFn {
+    /// Top k min values
+    MIN = 1,
+    /// Top k max values
+    MAX = 2,
+    /// Default option(max)
+    DEFAULT = 0,
+}
+
+/// Iterative Deconvolution Algorithm
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum IterativeDeconvAlgo {
+    /// Land-Weber Algorithm
+    LANDWEBER = 1,
+    /// Richardson-Lucy Algorithm
+    RICHARDSONLUCY = 2,
+    /// Default is Land-Weber algorithm
+    DEFAULT = 0,
+}
+
+/// Inverse Deconvolution Algorithm
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum InverseDeconvAlgo {
+    /// Tikhonov algorithm
+    TIKHONOV = 1,
+    /// Default is Tikhonov algorithm
+    DEFAULT = 0,
+}
+
+/// Gradient mode for convolution
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum ConvGradientType {
+    /// Filter Gradient
+    FILTER = 1,
+    /// Data Gradient
+    DATA = 2,
+    /// Biased Gradient
+    BIAS = 3,
+    /// Default is Data Gradient
+    DEFAULT = 0,
+}
+
+/// Gradient mode for convolution
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum VarianceBias {
+    /// Sample variance
+    SAMPLE = 1,
+    /// Population variance
+    POPULATION = 2,
+    /// Default (Population) variance
+    DEFAULT = 0,
+}
+
+/// Gradient mode for convolution
+#[repr(u32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub enum CublasMathMode {
+    /// To indicate use of Tensor Cores on CUDA capable GPUs
+    TENSOR_OP = 1,
+    /// Default i.e. tensor core operations will be avoided by the library
+    DEFAULT = 0,
+}
+
+#[cfg(test)]
+mod tests {
+    #[cfg(feature = "afserde")]
+    mod serde_tests {
+        #[test]
+        fn test_enum_serde() {
+            use super::super::AfError;
+
+            let err_code = AfError::ERR_NO_MEM;
+            let serd = match serde_json::to_string(&err_code) {
+                Ok(serialized_str) => serialized_str,
+                Err(e) => e.to_string(),
+            };
+            assert_eq!(serd, "\"ERR_NO_MEM\"");
+
+            let deserd: AfError = serde_json::from_str(&serd).unwrap();
+            assert_eq!(deserd, AfError::ERR_NO_MEM);
+        }
+
+        #[test]
+        fn test_scalar_serde() {
+            use super::super::Scalar;
+            use num::Complex;
+
+            let scalar = Scalar::C32(Complex {
+                re: 1.0f32,
+                im: 1.0f32,
+            });
+            let serd = match serde_json::to_string(&scalar) {
+                Ok(serialized_str) => serialized_str,
+                Err(e) => e.to_string(),
+            };
+
+            let deserd: Scalar = serde_json::from_str(&serd).unwrap();
+            assert_eq!(deserd, scalar);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/device.rs.html b/src/arrayfire/core/device.rs.html new file mode 100644 index 000000000..52cb5cac5 --- /dev/null +++ b/src/arrayfire/core/device.rs.html @@ -0,0 +1,721 @@ +device.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+
+use super::defines::AfError;
+use super::error::HANDLE_ERROR;
+use super::util::{dim_t, free_host, void_ptr};
+
+use libc::{c_char, c_int, size_t};
+use std::borrow::Cow;
+use std::ffi::{CStr, CString};
+
+extern "C" {
+    fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int;
+    fn af_get_revision() -> *const c_char;
+    fn af_info() -> c_int;
+    fn af_info_string(str: *mut *mut c_char, verbose: bool) -> c_int;
+    fn af_device_info(
+        d_name: *mut c_char,
+        d_platform: *mut c_char,
+        d_toolkit: *mut c_char,
+        d_compute: *mut c_char,
+    ) -> c_int;
+    fn af_init() -> c_int;
+    fn af_get_device_count(nDevices: *mut c_int) -> c_int;
+    fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int;
+    fn af_set_device(device: c_int) -> c_int;
+    fn af_get_device(device: *mut c_int) -> c_int;
+    fn af_device_mem_info(
+        alloc_bytes: *mut size_t,
+        alloc_buffers: *mut size_t,
+        lock_bytes: *mut size_t,
+        lock_buffers: *mut size_t,
+    ) -> c_int;
+    fn af_print_mem_info(msg: *const c_char, device_id: c_int) -> c_int;
+    fn af_set_mem_step_size(step_bytes: size_t) -> c_int;
+    fn af_get_mem_step_size(step_bytes: *mut size_t) -> c_int;
+    fn af_device_gc() -> c_int;
+    fn af_sync(device: c_int) -> c_int;
+
+    fn af_alloc_pinned(non_pagable_ptr: *mut void_ptr, bytes: dim_t) -> c_int;
+    fn af_free_pinned(non_pagable_ptr: void_ptr) -> c_int;
+    fn af_get_half_support(available: *mut c_int, device: c_int) -> c_int;
+}
+
+/// Get ArrayFire Version Number
+///
+/// # Return Values
+/// A triplet of integers indicating major, minor & fix release version numbers.
+pub fn get_version() -> (i32, i32, i32) {
+    unsafe {
+        let mut maj: i32 = 0;
+        let mut min: i32 = 0;
+        let mut pat: i32 = 0;
+        let err_val = af_get_version(
+            &mut maj as *mut c_int,
+            &mut min as *mut c_int,
+            &mut pat as *mut c_int,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (maj, min, pat)
+    }
+}
+
+/// Get ArrayFire Revision (commit) information of the library.
+///
+/// # Return Values
+/// This returns a `Cow<'static, str>` as the string is constructed at compile time.
+pub fn get_revision() -> Cow<'static, str> {
+    unsafe { CStr::from_ptr(af_get_revision()).to_string_lossy() }
+}
+
+/// Print library meta-info
+///
+/// # Examples
+///
+/// An example output of `af::info` call looks like below
+///
+/// ```text
+/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38)
+/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000
+/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0
+/// ```
+pub fn info() {
+    unsafe {
+        let err_val = af_info();
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Return library meta-info as `String`
+///
+/// # Examples
+///
+/// An example output of `af::info_string` call looks like below
+///
+/// ```text
+/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38)
+/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000
+/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0
+/// ```
+pub fn info_string(verbose: bool) -> String {
+    let result: String;
+    unsafe {
+        let mut tmp: *mut c_char = ::std::ptr::null_mut();
+        let err_val = af_info_string(&mut tmp, verbose);
+        HANDLE_ERROR(AfError::from(err_val));
+        result = CStr::from_ptr(tmp).to_string_lossy().into_owned();
+        free_host(tmp);
+    }
+    result
+}
+
+/// Gets the information about device and platform as strings.
+///
+/// # Return Values
+/// A tuple of `String` indicating the name, platform, toolkit and compute.
+pub fn device_info() -> (String, String, String, String) {
+    let mut name = [0 as c_char; 64];
+    let mut platform = [0 as c_char; 10];
+    let mut toolkit = [0 as c_char; 64];
+    let mut compute = [0 as c_char; 10];
+    unsafe {
+        let err_val = af_device_info(
+            &mut name[0],
+            &mut platform[0],
+            &mut toolkit[0],
+            &mut compute[0],
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (
+            CStr::from_ptr(name.as_mut_ptr())
+                .to_string_lossy()
+                .into_owned(),
+            CStr::from_ptr(platform.as_mut_ptr())
+                .to_string_lossy()
+                .into_owned(),
+            CStr::from_ptr(toolkit.as_mut_ptr())
+                .to_string_lossy()
+                .into_owned(),
+            CStr::from_ptr(compute.as_mut_ptr())
+                .to_string_lossy()
+                .into_owned(),
+        )
+    }
+}
+
+/// Initialize ArrayFire library
+///
+/// 0th device will be the default device unless init call
+/// is followed by set_device
+pub fn init() {
+    unsafe {
+        let err_val = af_init();
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get total number of available devices
+pub fn device_count() -> i32 {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_device_count(&mut temp as *mut c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp
+    }
+}
+
+/// Check if a device has double support
+///
+/// # Parameters
+///
+/// - `device` is the device for which double support is checked for
+///
+/// # Return Values
+///
+/// `True` if `device` device has double support, `False` otherwise.
+pub fn is_double_available(device: i32) -> bool {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_dbl_support(&mut temp as *mut c_int, device as c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp > 0
+    }
+}
+
+/// Set active device
+///
+/// # Parameters
+///
+/// - `device` is the value of the device identifier which has to be set as active
+pub fn set_device(device: i32) {
+    unsafe {
+        let err_val = af_set_device(device as c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get the current active device id
+pub fn get_device() -> i32 {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_device(&mut temp as *mut c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp
+    }
+}
+
+/// Get memory information from the memory manager for the current active device
+///
+/// # Parameters
+///
+/// This function doesn't take any input parameters
+///
+/// # Return Values
+///
+/// A quadruple of values regarding the following information.
+///
+/// * Number of bytes allocated
+/// * Number of buffers allocated
+/// * Number of bytes locked
+/// * Number of buffers locked
+pub fn device_mem_info() -> (usize, usize, usize, usize) {
+    unsafe {
+        let mut o0: usize = 0;
+        let mut o1: usize = 0;
+        let mut o2: usize = 0;
+        let mut o3: usize = 0;
+        let err_val = af_device_mem_info(
+            &mut o0 as *mut size_t,
+            &mut o1 as *mut size_t,
+            &mut o2 as *mut size_t,
+            &mut o3 as *mut size_t,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (o0, o1, o2, o3)
+    }
+}
+
+/// Print buffer details from the ArrayFire device manager
+///
+/// This information is printed in the form of a table.
+///
+/// # Parameters
+///
+/// - `msg` is a message to print before the table
+/// - `device` is the id of the device for which buffer details are to be printed
+///
+/// # Return Values
+///
+/// None
+pub fn print_mem_info(msg: String, device: i32) {
+    unsafe {
+        let cmsg = CString::new(msg.as_bytes());
+        match cmsg {
+            Ok(v) => {
+                let err_val = af_print_mem_info(
+                    v.to_bytes_with_nul().as_ptr() as *const c_char,
+                    device as c_int,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL),
+        }
+    }
+}
+
+/// Set the minimum memory chunk size
+///
+/// # Parameters
+///
+/// - `step_bytes` is the size of minimum memory chunk in bytes
+///
+/// # Return Values
+///
+/// None
+pub fn set_mem_step_size(step_bytes: usize) {
+    unsafe {
+        let err_val = af_set_mem_step_size(step_bytes as size_t);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get the minimum memory chunk size
+///
+/// # Parameters
+///
+/// None
+///
+/// # Return Values
+///
+/// Returns is the size of minimum memory chunk in bytes
+pub fn get_mem_step_size() -> usize {
+    unsafe {
+        let mut temp: usize = 0;
+        let err_val = af_get_mem_step_size(&mut temp as *mut size_t);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp
+    }
+}
+
+/// Call the garbage collection routine
+pub fn device_gc() {
+    unsafe {
+        let err_val = af_device_gc();
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Sync all operations on given device
+///
+/// # Parameters
+///
+/// - `device` on which the operations are to be synced
+///
+/// # Return Values
+///
+/// None
+pub fn sync(device: i32) {
+    unsafe {
+        let err_val = af_sync(device as c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Allocate non-pageable memory on HOST memory
+pub unsafe fn alloc_pinned(bytes: usize) -> void_ptr {
+    let mut out: void_ptr = std::ptr::null_mut();
+    let err_val = af_alloc_pinned(&mut out as *mut void_ptr, bytes as dim_t);
+    HANDLE_ERROR(AfError::from(err_val));
+    out
+}
+
+/// Free the pointer returned by [alloc_pinned](./fn.alloc_pinned.html)
+pub unsafe fn free_pinned(ptr: void_ptr) {
+    let err_val = af_free_pinned(ptr);
+    HANDLE_ERROR(AfError::from(err_val));
+}
+
+/// Check if a device has half support
+///
+/// # Parameters
+///
+/// - `device` is the device for which half precision support is checked for
+///
+/// # Return Values
+///
+/// `True` if `device` device has half support, `False` otherwise.
+pub fn is_half_available(device: i32) -> bool {
+    unsafe {
+        let mut temp: i32 = 0;
+        let err_val = af_get_half_support(&mut temp as *mut c_int, device as c_int);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp > 0
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/dim4.rs.html b/src/arrayfire/core/dim4.rs.html new file mode 100644 index 000000000..0da8237ac --- /dev/null +++ b/src/arrayfire/core/dim4.rs.html @@ -0,0 +1,307 @@ +dim4.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+
+use std::fmt;
+use std::ops::{Index, IndexMut};
+
+#[cfg(feature = "afserde")]
+use serde::{Deserialize, Serialize};
+
+/// Dim4 is used to store [Array](./struct.Array.html) dimensions
+#[derive(Copy, Clone, PartialEq, Debug)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+pub struct Dim4 {
+    dims: [u64; 4],
+}
+
+/// Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1]
+impl Default for Dim4 {
+    fn default() -> Self {
+        Self { dims: [1, 1, 1, 1] }
+    }
+}
+
+/// Enables index operation for Dim4
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::Dim4;
+///
+/// let dims = Dim4::new(&[4, 4, 2, 1]);
+/// println!("0th Dimension length is {}", dims[0]); // -> 4
+/// println!("1th Dimension length is {}", dims[1]); // -> 4
+/// println!("2th Dimension length is {}", dims[2]); // -> 2
+/// println!("3th Dimension length is {}", dims[3]); // -> 1
+/// ```
+impl Index<usize> for Dim4 {
+    type Output = u64;
+
+    fn index(&self, _index: usize) -> &u64 {
+        &self.dims[_index]
+    }
+}
+
+/// Enables index operation for Dim4 to modify dimensions
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::Dim4;
+///
+/// let mut dims = Dim4::new(&[4, 4, 2, 1]);
+/// dims[2] = 4;
+/// println!("Dimensions: {}", dims); // note that third dimension changed to 4
+/// ```
+impl IndexMut<usize> for Dim4 {
+    fn index_mut(&mut self, _index: usize) -> &mut Self::Output {
+        &mut self.dims[_index]
+    }
+}
+
+/// Enables use of Dim4 objects for printing it to display
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::Dim4;
+///
+/// let dims = Dim4::new(&[4, 4, 2, 1]);
+/// println!("0th Dimension length is {}", dims[0]); // -> 4
+/// ```
+impl fmt::Display for Dim4 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "[{} {} {} {}]",
+            self.dims[0], self.dims[1], self.dims[2], self.dims[3]
+        )
+    }
+}
+
+impl Dim4 {
+    /// Create Dim4 object
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use arrayfire::Dim4;
+    /// let dims = Dim4::new(&[4, 4, 2, 1]);
+    /// ```
+    pub fn new(dims: &[u64; 4]) -> Self {
+        Self {
+            dims: [dims[0], dims[1], dims[2], dims[3]],
+        }
+    }
+
+    /// Get the number of elements represented by Dim4 object
+    pub fn elements(&self) -> u64 {
+        self.dims[0] * self.dims[1] * self.dims[2] * self.dims[3]
+    }
+
+    /// Get the number of dimensions of Dim4
+    pub fn ndims(&self) -> usize {
+        let nelems = self.elements();
+        match nelems {
+            0 => 0,
+            1 => 1,
+            _ => {
+                if self.dims[3] != 1 {
+                    4
+                } else if self.dims[2] != 1 {
+                    3
+                } else if self.dims[1] != 1 {
+                    2
+                } else {
+                    1
+                }
+            }
+        }
+    }
+
+    /// Get the dimensions as a slice of 4 values
+    pub fn get(&self) -> &[u64; 4] {
+        &self.dims
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #[cfg(feature = "afserde")]
+    mod serde_tests {
+        use super::super::Dim4;
+        use crate::dim4;
+
+        #[test]
+        fn dim4_serde() {
+            let dims = dim4!(4, 4);
+            let serd = match serde_json::to_string(&dims) {
+                Ok(serialized_str) => serialized_str,
+                Err(e) => e.to_string(),
+            };
+            assert_eq!(serd, "{\"dims\":[4,4,1,1]}");
+
+            let deserd: Dim4 = serde_json::from_str(&serd).unwrap();
+            assert_eq!(deserd, dims);
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/error.rs.html b/src/arrayfire/core/error.rs.html new file mode 100644 index 000000000..88836c285 --- /dev/null +++ b/src/arrayfire/core/error.rs.html @@ -0,0 +1,239 @@ +error.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+
+use super::defines::AfError;
+use super::util::{dim_t, free_host};
+
+use libc::c_char;
+use std::ffi::CStr;
+use std::ops::{Deref, DerefMut};
+use std::sync::RwLock;
+
+extern "C" {
+    fn af_get_last_error(str: *mut *mut c_char, len: *mut dim_t);
+}
+
+/// Signature of error handling callback function
+pub type ErrorCallback = fn(AfError);
+
+/// Structure holding handle to callback function
+pub struct Callback {
+    cb: ErrorCallback,
+}
+
+impl Callback {
+    /// Associated function to create a new Callback object
+    pub fn new(callback: ErrorCallback) -> Self {
+        Self { cb: callback }
+    }
+
+    /// call invokes the error callback with `error_code`.
+    pub fn call(&self, error_code: AfError) {
+        (self.cb)(error_code)
+    }
+}
+
+/// Default error handling callback provided by ArrayFire crate
+pub fn handle_error_general(error_code: AfError) {
+    match error_code {
+        AfError::SUCCESS => {} /* No-op */
+        _ => panic!(
+            "Error message: {}\nLast error: {}",
+            error_code,
+            get_last_error()
+        ),
+    }
+}
+
+lazy_static! {
+    static ref ERROR_HANDLER_LOCK: RwLock<Callback> =
+        RwLock::new(Callback::new(handle_error_general));
+}
+
+/// Register user provided error handler
+///
+/// # Examples
+/// ```
+/// #[macro_use]
+/// extern crate arrayfire;
+///
+/// use arrayfire::{AfError, Callback, info, register_error_handler};
+/// use std::error::Error;
+///
+/// fn handle_error(error_code: AfError) {
+///     match error_code {
+///         AfError::SUCCESS => {}, /* No-op */
+///         _ => panic!("Error message: {}", error_code),
+///     }
+/// }
+///
+/// fn main() {
+///     //Registering the error handler should be the first call
+///     //before any other functions are called if your version
+///     //of error is to be used for subsequent function calls
+///     register_error_handler(Callback::new(handle_error));
+///
+///     info();
+/// }
+/// ```
+#[allow(clippy::match_wild_err_arm)]
+pub fn register_error_handler(cb_value: Callback) {
+    let mut gaurd = match ERROR_HANDLER_LOCK.write() {
+        Ok(g) => g,
+        Err(_) => panic!("Failed to acquire lock to register error handler"),
+    };
+
+    *gaurd.deref_mut() = cb_value;
+}
+
+/// Default error handler for error code returned by ArrayFire FFI calls
+#[allow(non_snake_case)]
+#[allow(clippy::match_wild_err_arm)]
+pub fn HANDLE_ERROR(error_code: AfError) {
+    let gaurd = match ERROR_HANDLER_LOCK.read() {
+        Ok(g) => g,
+        Err(_) => panic!("Failed to acquire lock while handling FFI return value"),
+    };
+
+    (*gaurd.deref()).call(error_code);
+}
+
+/// Fetch last error description as String
+pub fn get_last_error() -> String {
+    let mut result: String = String::from("No Last Error");
+    let mut tmp: *mut c_char = ::std::ptr::null_mut();
+    let mut len: dim_t = 0;
+    unsafe {
+        af_get_last_error(&mut tmp, &mut len as *mut dim_t);
+        if len > 0 {
+            result = CStr::from_ptr(tmp).to_string_lossy().into_owned();
+            free_host(tmp);
+        }
+    }
+    result
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/event.rs.html b/src/arrayfire/core/event.rs.html new file mode 100644 index 000000000..df960d498 --- /dev/null +++ b/src/arrayfire/core/event.rs.html @@ -0,0 +1,339 @@ +event.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+
+use super::defines::AfError;
+use super::error::HANDLE_ERROR;
+use super::util::af_event;
+
+use libc::c_int;
+use std::default::Default;
+
+extern "C" {
+    fn af_create_event(out: *mut af_event) -> c_int;
+    fn af_delete_event(out: af_event) -> c_int;
+    fn af_mark_event(out: af_event) -> c_int;
+    fn af_enqueue_wait_event(out: af_event) -> c_int;
+    fn af_block_event(out: af_event) -> c_int;
+}
+
+/// RAII construct to manage ArrayFire events
+///
+/// ## Sharing Across Threads
+///
+/// While sharing an Event with other threads, just move it across threads.
+pub struct Event {
+    event_handle: af_event,
+}
+
+unsafe impl Send for Event {}
+// No borrowed references are to be shared for Events, hence no sync trait
+
+impl Default for Event {
+    fn default() -> Self {
+        let mut temp: af_event = std::ptr::null_mut();
+        unsafe {
+            let err_val = af_create_event(&mut temp as *mut af_event);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+        Self { event_handle: temp }
+    }
+}
+
+impl Event {
+    /// Marks the event on the active computation queue.
+    ///
+    /// If the event is enqueued/waited on later, any operations that are currently
+    /// enqueued on the event queue will be completed before any events that are
+    /// enqueued after the call to enqueue
+    pub fn mark(&self) {
+        unsafe {
+            let err_val = af_mark_event(self.event_handle as af_event);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Enqueues the event and all enqueued events on the active queue
+    ///
+    /// All operations enqueued after a call to enqueue will not be executed
+    /// until operations on the queue when mark was called are complete
+    pub fn enqueue_wait(&self) {
+        unsafe {
+            let err_val = af_enqueue_wait_event(self.event_handle as af_event);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Blocks the calling thread on events until all events on the computation
+    /// stream before mark was called are complete
+    pub fn block(&self) {
+        unsafe {
+            let err_val = af_block_event(self.event_handle as af_event);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+}
+
+impl Drop for Event {
+    fn drop(&mut self) {
+        unsafe {
+            let ret_val = af_delete_event(self.event_handle as af_event);
+            match ret_val {
+                0 => (),
+                _ => panic!("Failed to delete event resources: {}", ret_val),
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::arith::pow;
+    use super::super::device::{info, set_device};
+    use super::super::event::Event;
+    use crate::{af_print, randu};
+    use std::sync::mpsc;
+    use std::thread;
+
+    #[test]
+    fn event_block() {
+        // This code example will try to compute the following expression
+        // using data-graph approach using threads, evens for illustration.
+        //
+        // (a * (b + c))^(d - 2)
+        //
+        // ANCHOR: event_block
+
+        // Set active GPU/device on main thread on which
+        // subsequent Array objects are created
+        set_device(0);
+        info();
+
+        let a = randu!(10, 10);
+        let b = randu!(10, 10);
+        let c = randu!(10, 10);
+        let d = randu!(10, 10);
+
+        let (tx, rx) = mpsc::channel();
+
+        thread::spawn(move || {
+            set_device(0);
+
+            let add_event = Event::default();
+
+            let add_res = b + c;
+
+            add_event.mark();
+            tx.send((add_res, add_event)).unwrap();
+
+            thread::sleep(std::time::Duration::new(10, 0));
+
+            let sub_event = Event::default();
+
+            let sub_res = d - 2;
+
+            sub_event.mark();
+            tx.send((sub_res, sub_event)).unwrap();
+        });
+
+        let (add_res, add_event) = rx.recv().unwrap();
+
+        println!("Got first message, waiting for addition result ...");
+        thread::sleep(std::time::Duration::new(5, 0));
+        // Perhaps, do some other tasks
+        add_event.block();
+
+        println!("Got addition result, now scaling it ... ");
+        let scaled = a * add_res;
+
+        let (sub_res, sub_event) = rx.recv().unwrap();
+
+        println!("Got message, waiting for subtraction result ...");
+        thread::sleep(std::time::Duration::new(5, 0));
+        // Perhaps, do some other tasks
+        sub_event.block();
+
+        let fin_res = pow(&scaled, &sub_res, false);
+
+        af_print!(
+            "Final result of the expression: ((a * (b + c))^(d - 2))",
+            &fin_res
+        );
+
+        // ANCHOR_END: event_block
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/index.rs.html b/src/arrayfire/core/index.rs.html new file mode 100644 index 000000000..b4c090de2 --- /dev/null +++ b/src/arrayfire/core/index.rs.html @@ -0,0 +1,1765 @@ +index.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+
+use super::array::Array;
+use super::defines::AfError;
+use super::error::HANDLE_ERROR;
+use super::seq::Seq;
+use super::util::{af_array, af_index_t, dim_t, HasAfEnum, IndexableType};
+
+use libc::{c_double, c_int, c_uint};
+use std::default::Default;
+use std::marker::PhantomData;
+use std::mem;
+
+extern "C" {
+    fn af_create_indexers(indexers: *mut af_index_t) -> c_int;
+    fn af_set_array_indexer(indexer: af_index_t, idx: af_array, dim: dim_t) -> c_int;
+    fn af_set_seq_indexer(
+        indexer: af_index_t,
+        idx: *const SeqInternal,
+        dim: dim_t,
+        is_batch: bool,
+    ) -> c_int;
+    fn af_release_indexers(indexers: af_index_t) -> c_int;
+
+    fn af_index(
+        out: *mut af_array,
+        input: af_array,
+        ndims: c_uint,
+        index: *const SeqInternal,
+    ) -> c_int;
+    fn af_lookup(out: *mut af_array, arr: af_array, indices: af_array, dim: c_uint) -> c_int;
+    fn af_assign_seq(
+        out: *mut af_array,
+        lhs: af_array,
+        ndims: c_uint,
+        indices: *const SeqInternal,
+        rhs: af_array,
+    ) -> c_int;
+    fn af_index_gen(
+        out: *mut af_array,
+        input: af_array,
+        ndims: dim_t,
+        indices: af_index_t,
+    ) -> c_int;
+    fn af_assign_gen(
+        out: *mut af_array,
+        lhs: af_array,
+        ndims: dim_t,
+        indices: af_index_t,
+        rhs: af_array,
+    ) -> c_int;
+}
+
+/// Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct)
+///
+/// ## Sharing Across Threads
+///
+/// While sharing an Indexer object with other threads, just move it across threads. At the
+/// moment, one cannot share borrowed references across threads.
+///
+/// # Examples
+///
+/// Given below are examples illustrating correct and incorrect usage of Indexer struct.
+///
+/// <h3> Correct Usage </h3>
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, randu, index_gen, Indexer};
+///
+/// // Always be aware of the fact that, the `Seq` or `Array` objects
+/// // that we intend to use for indexing via `Indexer` have to outlive
+/// // the `Indexer` object created in this context.
+///
+/// let dims    = Dim4::new(&[1, 3, 1, 1]);
+/// let indices = [1u8, 0, 1];
+/// let idx     = Array::new(&indices, dims);
+/// let values  = [2.0f32, 5.0, 6.0];
+/// let arr     = Array::new(&values, dims);
+///
+/// let mut idxr = Indexer::default();
+///
+/// // `idx` is created much before idxr, thus will
+/// // stay in scope at least as long as idxr
+/// idxr.set_index(&idx, 0, None);
+///
+/// index_gen(&arr, idxr);
+/// ```
+///
+/// <h3> Incorrect Usage </h3>
+///
+/// ```rust,ignore
+/// // Say, you create an Array on the fly and try
+/// // to call set_index, it will throw the given below
+/// // error or something similar to that
+/// idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
+/// ```
+///
+/// ```text
+/// error: borrowed value does not live long enough
+///   --> <anon>:16:55
+///   |
+///16 | idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None);
+///   |                 ----------------------------          ^ temporary value dropped here while still borrowed
+///   |                 |
+///   |                 temporary value created here
+///...
+///19 | }
+///   | - temporary value needs to live until here
+///   |
+///   = note: consider using a `let` binding to increase its lifetime
+/// ```
+pub struct Indexer<'object> {
+    handle: af_index_t,
+    count: usize,
+    marker: PhantomData<&'object ()>,
+}
+
+unsafe impl<'object> Send for Indexer<'object> {}
+
+/// Trait bound indicating indexability
+///
+/// Any object to be able to be passed on to [Indexer::set_index()](./struct.Indexer.html#method.set_index) method  should implement this trait with appropriate implementation of `set` method.
+pub trait Indexable {
+    /// Set indexing object for a given dimension
+    ///
+    /// `is_batch` parameter is not used in most cases as it has been provided in
+    /// ArrayFire C-API to enable GFOR construct in ArrayFire C++ API. This type
+    /// of construct/idea is not exposed in rust wrapper yet. So, the user would
+    /// just need to pass `None` to this parameter while calling this function.
+    /// Since we can't have default default values and we wanted to keep this
+    /// parameter for future use cases, we just made it an `std::Option`.
+    ///
+    /// # Parameters
+    ///
+    /// - `idxr` is mutable reference to [Indexer](./struct.Indexer.html) object which will
+    ///   be modified to set `self` indexable along `dim` dimension.
+    /// - `dim` is the dimension along which `self` indexable will be used for indexing.
+    /// - `is_batch` is only used if `self` is [Seq](./struct.Seq.html) to indicate if indexing
+    ///   along `dim` is a batched operation.
+    fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>);
+}
+
+/// Enables [Array](./struct.Array.html) to be used to index another Array
+///
+/// This is used in functions [index_gen](./fn.index_gen.html) and
+/// [assign_gen](./fn.assign_gen.html)
+impl<T> Indexable for Array<T>
+where
+    T: HasAfEnum + IndexableType,
+{
+    fn set(&self, idxr: &mut Indexer, dim: u32, _is_batch: Option<bool>) {
+        unsafe {
+            let err_val = af_set_array_indexer(idxr.get(), self.get(), dim as dim_t);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+}
+
+/// Enables [Seq](./struct.Seq.html) to be used to index another Array
+///
+/// This is used in functions [index_gen](./fn.index_gen.html) and
+/// [assign_gen](./fn.assign_gen.html)
+impl<T> Indexable for Seq<T>
+where
+    c_double: From<T>,
+    T: Copy + IndexableType,
+{
+    fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
+        unsafe {
+            let err_val = af_set_seq_indexer(
+                idxr.get(),
+                &SeqInternal::from_seq(self) as *const SeqInternal,
+                dim as dim_t,
+                match is_batch {
+                    Some(value) => value,
+                    None => false,
+                },
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+}
+
+impl<'object> Default for Indexer<'object> {
+    fn default() -> Self {
+        unsafe {
+            let mut temp: af_index_t = std::ptr::null_mut();
+            let err_val = af_create_indexers(&mut temp as *mut af_index_t);
+            HANDLE_ERROR(AfError::from(err_val));
+            Self {
+                handle: temp,
+                count: 0,
+                marker: PhantomData,
+            }
+        }
+    }
+}
+
+impl<'object> Indexer<'object> {
+    /// Create a new Indexer object and set the dimension specific index objects later
+    #[deprecated(since = "3.7.0", note = "Use Indexer::default() instead")]
+    pub fn new() -> Self {
+        unsafe {
+            let mut temp: af_index_t = std::ptr::null_mut();
+            let err_val = af_create_indexers(&mut temp as *mut af_index_t);
+            HANDLE_ERROR(AfError::from(err_val));
+            Self {
+                handle: temp,
+                count: 0,
+                marker: PhantomData,
+            }
+        }
+    }
+
+    /// Set either [Array](./struct.Array.html) or [Seq](./struct.Seq.html) to index an Array along `idx` dimension
+    pub fn set_index<'s, T>(&'s mut self, idx: &'object T, dim: u32, is_batch: Option<bool>)
+    where
+        T: Indexable + 'object,
+    {
+        idx.set(self, dim, is_batch);
+        self.count += 1;
+    }
+
+    /// Get number of indexing objects set
+    pub fn len(&self) -> usize {
+        self.count
+    }
+
+    /// Check if any indexing objects are set
+    pub fn is_empty(&self) -> bool {
+        self.count == 0
+    }
+
+    /// Get native(ArrayFire) resource handle
+    pub unsafe fn get(&self) -> af_index_t {
+        self.handle
+    }
+}
+
+impl<'object> Drop for Indexer<'object> {
+    fn drop(&mut self) {
+        unsafe {
+            let ret_val = af_release_indexers(self.handle as af_index_t);
+            match ret_val {
+                0 => (),
+                _ => panic!("Failed to release indexers resource: {}", ret_val),
+            }
+        }
+    }
+}
+
+/// Indexes the `input` Array using `seqs` Sequences
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, Seq, index, randu, print};
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
+/// let sub  = index(&a, seqs);
+/// println!("a(seq(1, 3, 1), span)");
+/// print(&sub);
+/// ```
+pub fn index<IO, T>(input: &Array<IO>, seqs: &[Seq<T>]) -> Array<IO>
+where
+    c_double: From<T>,
+    IO: HasAfEnum,
+    T: Copy + HasAfEnum + IndexableType,
+{
+    let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_index(
+            &mut temp as *mut af_array,
+            input.get(),
+            seqs.len() as u32,
+            seqs.as_ptr() as *const SeqInternal,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Extract `row_num` row from `input` Array
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, randu, row, print};
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// println!("Grab last row of the random matrix");
+/// print(&a);
+/// print(&row(&a, 4));
+/// ```
+pub fn row<T>(input: &Array<T>, row_num: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    index(
+        input,
+        &[
+            Seq::new(row_num as f64, row_num as f64, 1.0),
+            Seq::default(),
+        ],
+    )
+}
+
+/// Set `row_num`^th row in `inout` Array to a new Array `new_row`
+pub fn set_row<T>(inout: &mut Array<T>, new_row: &Array<T>, row_num: i64)
+where
+    T: HasAfEnum,
+{
+    let mut seqs = vec![Seq::new(row_num as f64, row_num as f64, 1.0)];
+    if inout.dims().ndims() > 1 {
+        seqs.push(Seq::default());
+    }
+    assign_seq(inout, &seqs, new_row)
+}
+
+/// Get an Array with all rows from `first` to `last` in the `input` Array
+pub fn rows<T>(input: &Array<T>, first: i64, last: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    index(
+        input,
+        &[Seq::new(first as f64, last as f64, step), Seq::default()],
+    )
+}
+
+/// Set rows from `first` to `last` in `inout` Array with rows from Array `new_rows`
+pub fn set_rows<T>(inout: &mut Array<T>, new_rows: &Array<T>, first: i64, last: i64)
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    let seqs = [Seq::new(first as f64, last as f64, step), Seq::default()];
+    assign_seq(inout, &seqs, new_rows)
+}
+
+/// Extract `col_num` col from `input` Array
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, randu, col, print};
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// print(&a);
+/// println!("Grab last col of the random matrix");
+/// print(&col(&a, 4));
+/// ```
+pub fn col<T>(input: &Array<T>, col_num: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    index(
+        input,
+        &[
+            Seq::default(),
+            Seq::new(col_num as f64, col_num as f64, 1.0),
+        ],
+    )
+}
+
+/// Set `col_num`^th col in `inout` Array to a new Array `new_col`
+pub fn set_col<T>(inout: &mut Array<T>, new_col: &Array<T>, col_num: i64)
+where
+    T: HasAfEnum,
+{
+    let seqs = [
+        Seq::default(),
+        Seq::new(col_num as f64, col_num as f64, 1.0),
+    ];
+    assign_seq(inout, &seqs, new_col)
+}
+
+/// Get all cols from `first` to `last` in the `input` Array
+pub fn cols<T>(input: &Array<T>, first: i64, last: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    index(
+        input,
+        &[Seq::default(), Seq::new(first as f64, last as f64, step)],
+    )
+}
+
+/// Set cols from `first` to `last` in `inout` Array with cols from Array `new_cols`
+pub fn set_cols<T>(inout: &mut Array<T>, new_cols: &Array<T>, first: i64, last: i64)
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    let seqs = [Seq::default(), Seq::new(first as f64, last as f64, step)];
+    assign_seq(inout, &seqs, new_cols)
+}
+
+/// Get `slice_num`^th slice from `input` Array
+///
+/// Slices indicate that the indexing is along 3rd dimension
+pub fn slice<T>(input: &Array<T>, slice_num: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let seqs = [
+        Seq::default(),
+        Seq::default(),
+        Seq::new(slice_num as f64, slice_num as f64, 1.0),
+    ];
+    index(input, &seqs)
+}
+
+/// Set slice `slice_num` in `inout` Array to a new Array `new_slice`
+///
+/// Slices indicate that the indexing is along 3rd dimension
+pub fn set_slice<T>(inout: &mut Array<T>, new_slice: &Array<T>, slice_num: i64)
+where
+    T: HasAfEnum,
+{
+    let seqs = [
+        Seq::default(),
+        Seq::default(),
+        Seq::new(slice_num as f64, slice_num as f64, 1.0),
+    ];
+    assign_seq(inout, &seqs, new_slice)
+}
+
+/// Get slices from `first` to `last` in `input` Array
+///
+/// Slices indicate that the indexing is along 3rd dimension
+pub fn slices<T>(input: &Array<T>, first: i64, last: i64) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    let seqs = [
+        Seq::default(),
+        Seq::default(),
+        Seq::new(first as f64, last as f64, step),
+    ];
+    index(input, &seqs)
+}
+
+/// Set `first` to `last` slices of `inout` Array to a new Array `new_slices`
+///
+/// Slices indicate that the indexing is along 3rd dimension
+pub fn set_slices<T>(inout: &mut Array<T>, new_slices: &Array<T>, first: i64, last: i64)
+where
+    T: HasAfEnum,
+{
+    let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 };
+    let seqs = [
+        Seq::default(),
+        Seq::default(),
+        Seq::new(first as f64, last as f64, step),
+    ];
+    assign_seq(inout, &seqs, new_slices)
+}
+
+/// Lookup(hash) an Array using another Array
+///
+/// Given a dimension `seq_dim`, `indices` are lookedup in `input` and returned as a new
+/// Array if found
+pub fn lookup<T, I>(input: &Array<T>, indices: &Array<I>, seq_dim: i32) -> Array<T>
+where
+    T: HasAfEnum,
+    I: HasAfEnum + IndexableType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_lookup(
+            &mut temp as *mut af_array,
+            input.get() as af_array,
+            indices.get() as af_array,
+            seq_dim as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Assign(copy) content of an Array to another Array indexed by Sequences
+///
+/// Assign `rhs` to `lhs` after indexing `lhs`
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{constant, Dim4, Seq, assign_seq, print};
+/// let mut a = constant(2.0 as f32, Dim4::new(&[5, 3, 1, 1]));
+/// print(&a);
+/// // 2.0 2.0 2.0
+/// // 2.0 2.0 2.0
+/// // 2.0 2.0 2.0
+/// // 2.0 2.0 2.0
+/// // 2.0 2.0 2.0
+///
+/// let b    = constant(1.0 as f32, Dim4::new(&[3, 3, 1, 1]));
+/// let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
+/// assign_seq(&mut a, seqs, &b);
+///
+/// print(&a);
+/// // 2.0 2.0 2.0
+/// // 1.0 1.0 1.0
+/// // 1.0 1.0 1.0
+/// // 1.0 1.0 1.0
+/// // 2.0 2.0 2.0
+/// ```
+pub fn assign_seq<T, I>(lhs: &mut Array<I>, seqs: &[Seq<T>], rhs: &Array<I>)
+where
+    c_double: From<T>,
+    I: HasAfEnum,
+    T: Copy + IndexableType,
+{
+    let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_assign_seq(
+            &mut temp as *mut af_array,
+            lhs.get() as af_array,
+            seqs.len() as c_uint,
+            seqs.as_ptr() as *const SeqInternal,
+            rhs.get() as af_array,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+
+        let modified = temp.into();
+        let _old_arr = mem::replace(lhs, modified);
+    }
+}
+
+/// Index an Array using any combination of Array's and Sequence's
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, Seq, print, randu, index_gen, Indexer};
+/// let values: [f32; 3] = [1.0, 2.0, 3.0];
+/// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+/// let seq4gen = Seq::new(0.0, 2.0, 1.0);
+/// let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// // [5 3 1 1]
+/// //     0.0000     0.2190     0.3835
+/// //     0.1315     0.0470     0.5194
+/// //     0.7556     0.6789     0.8310
+/// //     0.4587     0.6793     0.0346
+/// //     0.5328     0.9347     0.0535
+///
+///
+/// let mut idxrs = Indexer::default();
+/// idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
+/// idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
+///
+/// let sub2 = index_gen(&a, idxrs);
+/// println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+/// // [3 3 1 1]
+/// //     0.1315     0.0470     0.5194
+/// //     0.7556     0.6789     0.8310
+/// //     0.4587     0.6793     0.0346
+/// ```
+pub fn index_gen<T>(input: &Array<T>, indices: Indexer) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_index_gen(
+            &mut temp as *mut af_array,
+            input.get() as af_array,
+            indices.len() as dim_t,
+            indices.get() as af_index_t,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Assign an Array to another after indexing it using any combination of Array's and Sequence's
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Array, Dim4, Seq, print, randu, constant, Indexer, assign_gen};
+/// let values: [f32; 3] = [1.0, 2.0, 3.0];
+/// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+/// let seq4gen = Seq::new(0.0, 2.0, 1.0);
+/// let mut a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// // [5 3 1 1]
+/// //     0.0000     0.2190     0.3835
+/// //     0.1315     0.0470     0.5194
+/// //     0.7556     0.6789     0.8310
+/// //     0.4587     0.6793     0.0346
+/// //     0.5328     0.9347     0.0535
+///
+/// let b    = constant(2.0 as f32, Dim4::new(&[3, 3, 1, 1]));
+///
+/// let mut idxrs = Indexer::default();
+/// idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
+/// idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
+///
+/// assign_gen(&mut a, &idxrs, &b);
+/// println!("a(indices, seq(0, 2, 1))"); print(&a);
+/// // [5 3 1 1]
+/// //     0.0000     0.2190     0.3835
+/// //     2.0000     2.0000     2.0000
+/// //     2.0000     2.0000     2.0000
+/// //     2.0000     2.0000     2.0000
+/// //     0.5328     0.9347     0.0535
+/// ```
+pub fn assign_gen<T>(lhs: &mut Array<T>, indices: &Indexer, rhs: &Array<T>)
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_assign_gen(
+            &mut temp as *mut af_array,
+            lhs.get() as af_array,
+            indices.len() as dim_t,
+            indices.get() as af_index_t,
+            rhs.get() as af_array,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+
+        let modified = temp.into();
+        let _old_arr = mem::replace(lhs, modified);
+    }
+}
+
+#[repr(C)]
+struct SeqInternal {
+    begin: c_double,
+    end: c_double,
+    step: c_double,
+}
+
+impl SeqInternal {
+    fn from_seq<T>(s: &Seq<T>) -> Self
+    where
+        c_double: From<T>,
+        T: Copy + IndexableType,
+    {
+        Self {
+            begin: From::from(s.begin()),
+            end: From::from(s.end()),
+            step: From::from(s.step()),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::array::Array;
+    use super::super::data::constant;
+    use super::super::device::set_device;
+    use super::super::dim4::Dim4;
+    use super::super::index::{assign_gen, assign_seq, col, index, index_gen, row, Indexer};
+    use super::super::index::{cols, rows};
+    use super::super::random::randu;
+    use super::super::seq::Seq;
+
+    use crate::{dim4, seq, view};
+
+    #[test]
+    fn non_macro_seq_index() {
+        set_device(0);
+        // ANCHOR: non_macro_seq_index
+        let dims = Dim4::new(&[5, 5, 1, 1]);
+        let a = randu::<f32>(dims);
+        //af_print!("a", a);
+        //a
+        //[5 5 1 1]
+        //    0.3990     0.5160     0.8831     0.9107     0.6688
+        //    0.6720     0.3932     0.0621     0.9159     0.8434
+        //    0.5339     0.2706     0.7089     0.0231     0.1328
+        //    0.1386     0.9455     0.9434     0.2330     0.2657
+        //    0.7353     0.1587     0.1227     0.2220     0.2299
+
+        // Index array using sequences
+        let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
+        let _sub = index(&a, seqs);
+        //af_print!("a(seq(1,3,1), span)", sub);
+        // [3 5 1 1]
+        //     0.6720     0.3932     0.0621     0.9159     0.8434
+        //     0.5339     0.2706     0.7089     0.0231     0.1328
+        //     0.1386     0.9455     0.9434     0.2330     0.2657
+        // ANCHOR_END: non_macro_seq_index
+    }
+
+    #[test]
+    fn seq_index() {
+        set_device(0);
+        // ANCHOR: seq_index
+        let dims = dim4!(5, 5, 1, 1);
+        let a = randu::<f32>(dims);
+        let first3 = seq!(1:3:1);
+        let allindim2 = seq!();
+        let _sub = view!(a[first3, allindim2]);
+        // ANCHOR_END: seq_index
+    }
+
+    #[test]
+    fn non_macro_seq_assign() {
+        set_device(0);
+        // ANCHOR: non_macro_seq_assign
+        let mut a = constant(2.0 as f32, dim4!(5, 3));
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+        // 2.0 2.0 2.0
+
+        let b = constant(1.0 as f32, dim4!(3, 3));
+        let seqs = [seq!(1:3:1), seq!()];
+        assign_seq(&mut a, &seqs, &b);
+        //print(&a);
+        // 2.0 2.0 2.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 1.0 1.0 1.0
+        // 2.0 2.0 2.0
+        // ANCHOR_END: non_macro_seq_assign
+    }
+
+    #[test]
+    fn non_macro_seq_array_index() {
+        set_device(0);
+        // ANCHOR: non_macro_seq_array_index
+        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = Seq::new(0.0, 2.0, 1.0);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        // [5 3 1 1]
+        //     0.0000     0.2190     0.3835
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+        //     0.5328     0.9347     0.0535
+
+        let mut idxrs = Indexer::default();
+        idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+        idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+        let _sub2 = index_gen(&a, idxrs);
+        //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+        // [3 3 1 1]
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+        // ANCHOR_END: non_macro_seq_array_index
+    }
+
+    #[test]
+    fn seq_array_index() {
+        set_device(0);
+        // ANCHOR: seq_array_index
+        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
+        let seq4gen = seq!(0:2:1);
+        let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+        let _sub2 = view!(a[indices, seq4gen]);
+        // ANCHOR_END: seq_array_index
+    }
+
+    #[test]
+    fn non_macro_seq_array_assign() {
+        set_device(0);
+        // ANCHOR: non_macro_seq_array_assign
+        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, dim4!(3, 1, 1, 1));
+        let seq4gen = seq!(0:2:1);
+        let mut a = randu::<f32>(dim4!(5, 3, 1, 1));
+        // [5 3 1 1]
+        //     0.0000     0.2190     0.3835
+        //     0.1315     0.0470     0.5194
+        //     0.7556     0.6789     0.8310
+        //     0.4587     0.6793     0.0346
+        //     0.5328     0.9347     0.0535
+
+        let b = constant(2.0 as f32, dim4!(3, 3, 1, 1));
+
+        let mut idxrs = Indexer::default();
+        idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
+        idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
+
+        let _sub2 = assign_gen(&mut a, &idxrs, &b);
+        //println!("a(indices, seq(0, 2, 1))"); print(&sub2);
+        // [5 3 1 1]
+        //     0.0000     0.2190     0.3835
+        //     2.0000     2.0000     2.0000
+        //     2.0000     2.0000     2.0000
+        //     2.0000     2.0000     2.0000
+        //     0.5328     0.9347     0.0535
+        // ANCHOR_END: non_macro_seq_array_assign
+    }
+
+    #[test]
+    fn setrow() {
+        set_device(0);
+        // ANCHOR: setrow
+        let a = randu::<f32>(dim4!(5, 5, 1, 1));
+        //print(&a);
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, 4);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, 4);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+        // ANCHOR_END: setrow
+    }
+
+    #[test]
+    fn get_row() {
+        set_device(0);
+        // ANCHOR: get_row
+        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = row(&a, -1);
+        // [1 5 1 1]
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = col(&a, -1);
+        // [5 1 1 1]
+        //     0.6755
+        //     0.6105
+        //     0.5232
+        //     0.5567
+        //     0.7896
+        // ANCHOR_END: get_row
+    }
+
+    #[test]
+    fn get_rows() {
+        set_device(0);
+        // ANCHOR: get_rows
+        let a = randu::<f32>(dim4!(5, 5));
+        // [5 5 1 1]
+        //     0.6010     0.5497     0.1583     0.3636     0.6755
+        //     0.0278     0.2864     0.3712     0.4165     0.6105
+        //     0.9806     0.3410     0.3543     0.5814     0.5232
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _r = rows(&a, -1, -2);
+        // [2 5 1 1]
+        //     0.2126     0.7509     0.6450     0.8962     0.5567
+        //     0.0655     0.4105     0.9675     0.3712     0.7896
+        let _c = cols(&a, -1, -3);
+        // [5 3 1 1]
+        //     0.1583     0.3636     0.6755
+        //     0.3712     0.4165     0.6105
+        //     0.3543     0.5814     0.5232
+        //     0.6450     0.8962     0.5567
+        //     0.9675     0.3712     0.7896
+        // ANCHOR_END: get_rows
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/macros.rs.html b/src/arrayfire/core/macros.rs.html new file mode 100644 index 000000000..96998f1d9 --- /dev/null +++ b/src/arrayfire/core/macros.rs.html @@ -0,0 +1,1033 @@ +macros.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+
+/// Macro to print the current stats of ArrayFire's memory manager.
+///
+/// `mem_info!` print 4 values:
+///
+///  Name                    | Description
+/// -------------------------|-------------------------
+///  Allocated Bytes         | Total number of bytes allocated by the memory manager
+///  Allocated Buffers       | Total number of buffers allocated
+///  Locked (In Use) Bytes   | Number of bytes that are in use by active arrays
+///  Locked (In Use) Buffers | Number of buffers that are in use by active arrays
+///
+///  The `Allocated Bytes` is always a multiple of the memory step size. The
+///  default step size is 1024 bytes. This means when a buffer is to be
+///  allocated, the size is always rounded up to a multiple of the step size.
+///  You can use [get_mem_step_size](./fn.get_mem_step_size.html) to check the
+///  current step size and [set_mem_step_size](./fn.set_mem_step_size.html) to
+///  set a custom resolution size.
+///
+///  The `Allocated Buffers` is the number of buffers that use up the allocated
+///  bytes. This includes buffers currently in scope, as well as buffers marked
+///  as free, ie, from arrays gone out of scope. The free buffers are available
+///  for use by new arrays that might be created.
+///
+///  The `Locked Bytes` is the number of bytes in use that cannot be
+///  reallocated at the moment. The difference of Allocated Bytes and Locked
+///  Bytes is the total bytes available for reallocation.
+///
+///  The `Locked Buffers` is the number of buffer in use that cannot be
+///  reallocated at the moment. The difference of Allocated Buffers and Locked
+///  Buffers is the number of buffers available for reallocation.
+///
+/// # Parameters
+///
+/// - `msg` is the message that is printed to screen before printing stats
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, device_mem_info, print, randu, mem_info};
+///
+/// let dims = Dim4::new(&[5, 5, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// print(&a);
+/// mem_info!("Hello!");
+/// ```
+///
+/// Sample Output:
+///
+/// ```text
+/// AF Memory: Here
+/// Allocated [ Bytes | Buffers ] = [ 4096 | 4 ]
+/// In Use    [ Bytes | Buffers ] = [ 2048 | 2 ]
+/// ```
+#[macro_export]
+macro_rules! mem_info {
+    [$msg: expr] => {
+        {
+            let (abytes, abuffs, lbytes, lbuffs) = $crate::device_mem_info();
+            println!("AF Memory: {:?}", $msg);
+            println!("Allocated [Bytes | Buffers] = [ {} | {} ]", abytes, abuffs);
+            println!("In Use    [Bytes | Buffers] = [ {} | {} ]", lbytes, lbuffs);
+        }
+    };
+}
+
+/// Join multiple Arrays along a given dimension
+///
+/// All the Arrays provided to this macro should be of type `&Array`
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, join_many, print, randu};
+///
+/// let a = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// let b = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// let c = &randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
+/// let d = join_many![2; a, b, c];
+/// print(&d);
+/// ```
+///
+/// # Panics
+///
+/// This macro just calls [join_many](./fn.join_many.html) function after collecting all
+/// the input arrays into a vector.
+// Using macro to implement join many wrapper
+#[macro_export]
+macro_rules! join_many {
+    [$dim: expr; $($x:expr),+] => {
+        {
+            let mut temp_vec = Vec::new();
+            $(
+                temp_vec.push($x);
+             )*
+            $crate::join_many($dim, temp_vec)
+        }
+    };
+}
+
+/// Print given message before printing out the Array to standard output
+///
+/// # Examples
+///
+/// ```rust
+/// use arrayfire::{Dim4, print_gen, randu, af_print};
+/// let dims = Dim4::new(&[3, 1, 1, 1]);
+/// let a = randu::<f32>(dims);
+/// af_print!("Create a 5-by-3 matrix of random floats on the GPU", a);
+/// ```
+///
+#[macro_export]
+macro_rules! af_print {
+    [$msg: expr, $x: expr] => {
+        {
+            $crate::print_gen(String::from($msg), &$x, Some(4));
+        }
+    };
+}
+
+/// Create a dim4 object from provided dimensions
+///
+/// The user can pass 1 or more sizes and the left over values will default to 1.
+#[macro_export]
+macro_rules! dim4 {
+    ($dim0:expr) => {
+        $crate::Dim4::new(&[$dim0, 1, 1, 1])
+    };
+    ($dim0:expr, $dim1:expr) => {
+        $crate::Dim4::new(&[$dim0, $dim1, 1, 1])
+    };
+    ($dim0:expr, $dim1:expr, $dim2:expr) => {
+        $crate::Dim4::new(&[$dim0, $dim1, $dim2, 1])
+    };
+    ($dim0:expr, $dim1:expr, $dim2:expr, $dim3:expr) => {
+        $crate::Dim4::new(&[$dim0, $dim1, $dim2, $dim3])
+    };
+}
+
+/// Create a sequence object
+///
+/// If type is not provided, then the Seq will default to i32 type
+#[macro_export]
+macro_rules! seq {
+    () => {
+        $crate::Seq::<i32>::default()
+    };
+    ($sty:ty; $start:literal : $end:literal : $step:literal) => {
+        $crate::Seq::<$sty>::new($start, $end, $step)
+    };
+    ($start:literal : $end:literal : $step:literal) => {
+        $crate::Seq::<i32>::new($start, $end, $step)
+    };
+    ($sty:ty; $start:expr , $end:expr , $step:expr) => {
+        $crate::Seq::<$sty>::new($start, $end, $step)
+    };
+    ($start:expr , $end:expr , $step:expr) => {
+        $crate::Seq::<i32>::new($start, $end, $step)
+    };
+}
+
+/// Indexing into an existing Array
+///
+/// This macro call with return an Array that has a view of another Array. The Array returned due to
+/// the indexing operation will follow copy-on-write semantics. The Array identifier taken by this
+/// macro is passed to the relevant internal functions as a borrowed reference. Thus, this identifier
+/// will be still available for futher use after the macro call.
+///
+/// The following types of inputs are matched by this macro.
+///
+/// - A simple Array identifier.
+/// - An Array with slicing info for indexing.
+/// - An Array with slicing info and other arrays used for indexing.
+///
+/// Examples on how to use this macro are provided in the [tutorials book][1]
+///
+/// [1]: http://arrayfire.org/arrayfire-rust/book/indexing.html
+#[macro_export]
+macro_rules! view {
+    (@af_max_dims) => {
+        4
+    };
+    ( $array_ident:ident ) => {
+        $array_ident.clone()
+    };
+    ( $array_ident:ident [ $($start:literal : $end:literal : $step:literal),+ ] ) => {
+        {
+            #[allow(non_snake_case)]
+            let AF_MAX_DIMS: usize = view!(@af_max_dims);
+            let mut seq_vec = Vec::<$crate::Seq<i32>>::with_capacity(AF_MAX_DIMS);
+            $(
+                seq_vec.push($crate::seq!($start:$end:$step));
+             )*
+            $crate::index(&$array_ident, &seq_vec)
+        }
+    };
+    (@set_indexer $idim:expr, $idxr:ident, $lterm:expr) => {
+        {
+            $idxr.set_index(&$lterm, $idim, None);
+        }
+    };
+    (@set_indexer $idim:expr, $idxr:ident, $hterm:expr, $($tterm:expr),*) => {
+        {
+            $idxr.set_index(&$hterm, $idim, None);
+            view!(@set_indexer $idim + 1, $idxr, $($tterm),*);
+        }
+    };
+    ($array_ident:ident [ $($_e:expr),+ ]) => {
+        {
+            let mut idxrs = $crate::Indexer::default();
+            view!(@set_indexer 0, idxrs, $($_e),*);
+            $crate::index_gen(&$array_ident, idxrs)
+        }
+    };
+}
+
+/// Macro to evaluate individual Arrays or assignment operations
+///
+/// - Evaluate on one or more Array identifiers: essentially calls [Array::eval][4] on each of those
+///   Array objects individually.
+///
+///   ```rust
+///   use arrayfire::{dim4, eval, randu};
+///   let dims = dim4!(5, 5);
+///   let a = randu::<f32>(dims);
+///   let b = a.clone();
+///   let c = a.clone();
+///   let d = a.clone();
+///   let x = a - b;
+///   let y = c * d;
+///   eval!(&x, &y);
+///   ```
+///
+/// - Evaluate assignment operations: This is essentially syntactic sugar for modifying portions of
+///   Array with another Array using a combination of [Sequences][1] and/or [Array][2] objects.
+///   Full examples for this use case are provided in the [tutorials book][3]
+///
+/// [1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Seq.html
+/// [2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html
+/// [3]: http://arrayfire.org/arrayfire-rust/book/indexing.html
+/// [4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.eval
+#[macro_export]
+macro_rules! eval {
+    ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] =
+      $r:ident [ $($rb:literal : $re:literal : $rs:literal),+ ]) => {
+        {
+            #[allow(non_snake_case)]
+            let AF_MAX_DIMS: usize = view!(@af_max_dims);
+            let mut seq_vec = Vec::<$crate::Seq<i32>>::with_capacity(AF_MAX_DIMS);
+            $(
+                seq_vec.push($crate::seq!($lb:$le:$ls));
+             )*
+            let mut idxrs = $crate::Indexer::default();
+            for i in 0..seq_vec.len() {
+                idxrs.set_index(&seq_vec[i], i as u32, None);
+            }
+            let eq_rterm = $crate::view!($r[ $($rb:$re:$rs),+ ]);
+            $crate::assign_gen(&mut $l, &idxrs, &eq_rterm);
+        }
+    };
+    ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] = $r:expr ) => {
+        {
+            #[allow(non_snake_case)]
+            let AF_MAX_DIMS: usize = view!(@af_max_dims);
+            let mut seq_vec = Vec::<$crate::Seq<i32>>::with_capacity(AF_MAX_DIMS);
+            $(
+                seq_vec.push($crate::seq!($lb:$le:$ls));
+             )*
+            let mut idxrs = $crate::Indexer::default();
+            for i in 0..seq_vec.len() {
+                idxrs.set_index(&seq_vec[i], i as u32, None);
+            }
+            $crate::assign_gen(&mut $l, &idxrs, &$r);
+        }
+    };
+    ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:ident [ $($rhs_e:expr),+ ]) => {
+        {
+            let eq_rterm = $crate::view!($rhs[ $($rhs_e),+ ]);
+            let mut idxrs = $crate::Indexer::default();
+            view!(@set_indexer 0, idxrs, $($lhs_e),*);
+            $crate::assign_gen(&mut $lhs, &idxrs, &eq_rterm);
+        }
+    };
+    ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:expr) => {
+        {
+            let mut idxrs = $crate::Indexer::default();
+            view!(@set_indexer 0, idxrs, $($lhs_e),*);
+            $crate::assign_gen(&mut $lhs, &idxrs, &$rhs);
+        }
+    };
+    [$($x:expr),+] => {
+        {
+            let mut temp_vec = Vec::new();
+            $(
+                temp_vec.push($x);
+             )*
+            $crate::eval_multiple(temp_vec)
+        }
+    };
+}
+
+/// Create an array of given shape filled with a single value a.k.a constant array
+///
+/// # Examples
+///
+/// ```rust
+/// # use arrayfire::{constant};
+/// let _zeros_1d = constant!(0.0f32; 10);
+/// let _ones_3d = constant!(1u32; 3, 3, 3);
+///
+/// let dim = 10;
+/// let mix_shape = constant!(42.0f32; dim, 10);
+/// ```
+#[macro_export]
+macro_rules! constant {
+    ($value:expr; $($dim:expr),+) => {
+        $crate::constant($value, $crate::dim4!($($dim),*))
+    };
+}
+
+/// Create an array of given shape sampled from uniform distribution
+///
+/// If no type argument is specified, the data type defaults to 32 bit floats.
+///
+/// # Examples
+///
+/// ```rust
+/// # use arrayfire::{randu};
+/// let mat10x10 = randu!(10, 10);
+/// ```
+#[macro_export]
+macro_rules! randu {
+    ($($dim:expr),+) => { $crate::randu::<f32>($crate::dim4!($($dim),*)) };
+    ($type:ty; $($dim:expr),+) => { $crate::randu::<$type>($crate::dim4!($($dim),*)) };
+}
+
+/// Create an array of given shape sampled from normal distribution
+///
+/// If no type argument is specified, the data type defaults to 32 bit floats.
+///
+/// # Examples
+///
+/// ```rust
+/// # use arrayfire::{randn};
+/// let mat10x10 = randn!(10, 10);
+/// ```
+#[macro_export]
+macro_rules! randn {
+    ($($dim:expr),+) => { $crate::randn::<f32>($crate::dim4!($($dim),*)) };
+    ($type:ty; $($dim:expr),+) => { $crate::randn::<$type>($crate::dim4!($($dim),*)) };
+}
+
+#[cfg(test)]
+mod tests {
+    use super::super::array::Array;
+    use super::super::data::constant;
+    use super::super::device::set_device;
+    use super::super::index::index;
+    use super::super::random::randu;
+
+    #[test]
+    fn dim4_construction() {
+        let dim1d = dim4!(2);
+        let dim2d = dim4!(2, 3);
+        let dim3d = dim4!(2, 3, 4);
+        let dim4d = dim4!(2, 3, 4, 2);
+        let _dimn = dim4!(dim1d[0], dim2d[1], dim3d[2], dim4d[3]);
+    }
+
+    #[test]
+    fn seq_construction() {
+        let default_seq = seq!();
+        let _range_1_to_10_step_1 = seq!(0:9:1);
+        let _range_1_to_10_step_1_2 = seq!(f32; 0.0:9.0:1.5);
+        let _range_from_exprs = seq!(default_seq.begin(), default_seq.end(), default_seq.step());
+        let _range_from_exprs2 = seq!(f32; default_seq.begin() as f32,
+                 default_seq.end() as f32, default_seq.step() as f32);
+    }
+
+    #[test]
+    fn seq_view() {
+        set_device(0);
+        let mut dim4d = dim4!(5, 3, 2, 1);
+        dim4d[2] = 1;
+
+        let a = randu::<f32>(dim4d);
+        let seqs = &[seq!(1:3:1), seq!()];
+        let _sub = index(&a, seqs);
+    }
+
+    #[test]
+    fn seq_view2() {
+        set_device(0);
+        // ANCHOR: seq_view2
+        let a = randu::<f32>(dim4!(5, 5));
+        let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis
+
+        // ANCHOR_END: seq_view2
+    }
+
+    #[test]
+    fn view_macro() {
+        set_device(0);
+        let dims = dim4!(5, 5, 2, 1);
+        let a = randu::<f32>(dims);
+        let b = a.clone();
+        let c = a.clone();
+        let d = a.clone();
+        let e = a.clone();
+
+        let _v = view!(a);
+
+        let _m = view!(c[1:3:1, 1:3:2]);
+
+        let x = seq!(1:3:1);
+        let y = seq!(1:3:2);
+        let _u = view!(b[x, y]);
+
+        let values: [u32; 3] = [1, 2, 3];
+        let indices = Array::new(&values, dim4!(3, 1, 1, 1));
+        let indices2 = Array::new(&values, dim4!(3, 1, 1, 1));
+
+        let _w = view!(d[indices, indices2]);
+
+        let _z = view!(e[indices, y]);
+    }
+
+    #[test]
+    fn eval_assign_seq_indexed_array() {
+        set_device(0);
+        let dims = dim4!(5, 5);
+        let mut a = randu::<f32>(dims);
+        //print(&a);
+        //[5 5 1 1]
+        //    0.6010     0.5497     0.1583     0.3636     0.6755
+        //    0.0278     0.2864     0.3712     0.4165     0.6105
+        //    0.9806     0.3410     0.3543     0.5814     0.5232
+        //    0.2126     0.7509     0.6450     0.8962     0.5567
+        //    0.0655     0.4105     0.9675     0.3712     0.7896
+
+        let b = randu::<f32>(dims);
+        //print(&b);
+        //[5 5 1 1]
+        //    0.8966     0.5143     0.0123     0.7917     0.2522
+        //    0.0536     0.3670     0.3988     0.1654     0.9644
+        //    0.5775     0.3336     0.9787     0.8657     0.4711
+        //    0.2908     0.0363     0.2308     0.3766     0.3637
+        //    0.9941     0.5349     0.6244     0.7331     0.9643
+
+        let d0 = seq!(1:2:1);
+        let d1 = seq!(1:2:1);
+        let s0 = seq!(1:2:1);
+        let s1 = seq!(1:2:1);
+        eval!(a[d0, d1] = b[s0, s1]);
+        //print(&a);
+        //[5 5 1 1]
+        //    0.6010     0.5497     0.1583     0.3636     0.6755
+        //    0.0278     0.3670     0.3988     0.4165     0.6105
+        //    0.9806     0.3336     0.9787     0.5814     0.5232
+        //    0.2126     0.7509     0.6450     0.8962     0.5567
+        //    0.0655     0.4105     0.9675     0.3712     0.7896
+    }
+
+    #[test]
+    fn eval_assign_array_to_seqd_array() {
+        set_device(0);
+        // ANCHOR: macro_seq_assign
+        let mut a = randu::<f32>(dim4!(5, 5));
+        let b = randu::<f32>(dim4!(2, 2));
+        eval!(a[1:2:1, 1:2:1] = b);
+        // ANCHOR_END: macro_seq_assign
+    }
+
+    #[test]
+    fn macro_seq_array_assign() {
+        set_device(0);
+        // ANCHOR: macro_seq_array_assign
+        let values: [f32; 3] = [1.0, 2.0, 3.0];
+        let indices = Array::new(&values, dim4!(3));
+        let seq4gen = seq!(0:2:1);
+        let mut a = randu::<f32>(dim4!(5, 3));
+
+        let b = constant(2.0 as f32, dim4!(3, 3));
+
+        eval!(a[indices, seq4gen] = b);
+        // ANCHOR_END: macro_seq_array_assign
+    }
+
+    #[test]
+    fn constant_macro() {
+        set_device(0);
+        let _zeros_1d = constant!(0.0f32; 10);
+        let _zeros_2d = constant!(0.0f64; 5, 5);
+        let _ones_3d = constant!(1u32; 3, 3, 3);
+        let _twos_4d = constant!(2u16; 2, 2, 2, 2);
+
+        let dim = 10;
+        let _mix_shape = constant!(42.0f32; dim, 10);
+    }
+
+    #[test]
+    fn rand_macro() {
+        set_device(0);
+        let _ru5x5 = randu!(5, 5);
+        let _rn5x5 = randn!(5, 5);
+        let _ruu32_5x5 = randu!(u32; 5, 5);
+        let _ruu8_5x5 = randu!(u8; 5, 5);
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/mod.rs.html b/src/arrayfire/core/mod.rs.html new file mode 100644 index 000000000..e0473e708 --- /dev/null +++ b/src/arrayfire/core/mod.rs.html @@ -0,0 +1,119 @@ +mod.rs - source + + + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+
+#[cfg(feature = "arithmetic")]
+pub use arith::*;
+#[cfg(feature = "arithmetic")]
+mod arith;
+
+pub use array::*;
+mod array;
+
+pub use backend::*;
+mod backend;
+
+#[cfg(feature = "data")]
+pub use data::*;
+#[cfg(feature = "data")]
+mod data;
+
+pub use defines::*;
+mod defines;
+
+pub use dim4::Dim4;
+mod dim4;
+
+pub use device::*;
+mod device;
+
+pub use error::*;
+mod error;
+
+pub use event::*;
+mod event;
+
+#[cfg(feature = "indexing")]
+pub use index::*;
+#[cfg(feature = "indexing")]
+mod index;
+
+#[cfg(feature = "macros")]
+mod macros;
+
+#[cfg(feature = "random")]
+pub use random::*;
+#[cfg(feature = "random")]
+mod random;
+
+#[cfg(feature = "indexing")]
+pub use seq::Seq;
+#[cfg(feature = "indexing")]
+mod seq;
+
+pub use util::*;
+mod util;
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/random.rs.html b/src/arrayfire/core/random.rs.html new file mode 100644 index 000000000..adec8a1a1 --- /dev/null +++ b/src/arrayfire/core/random.rs.html @@ -0,0 +1,763 @@ +random.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+
+use super::array::Array;
+use super::defines::{AfError, RandomEngineType};
+use super::dim4::Dim4;
+use super::error::HANDLE_ERROR;
+use super::util::{af_array, af_random_engine, dim_t, u64_t, FloatingPoint, HasAfEnum};
+
+use libc::{c_int, c_uint};
+
+extern "C" {
+    fn af_set_seed(seed: u64_t) -> c_int;
+    fn af_get_seed(seed: *mut u64_t) -> c_int;
+
+    fn af_randu(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint) -> c_int;
+    fn af_randn(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint) -> c_int;
+
+    fn af_create_random_engine(engine: *mut af_random_engine, rtype: c_uint, seed: u64_t) -> c_int;
+    fn af_retain_random_engine(
+        engine: *mut af_random_engine,
+        inputEngine: af_random_engine,
+    ) -> c_int;
+    fn af_random_engine_set_type(engine: *mut af_random_engine, rtpye: c_uint) -> c_int;
+    fn af_random_engine_get_type(rtype: *mut c_uint, engine: af_random_engine) -> c_int;
+    fn af_random_engine_set_seed(engine: *mut af_random_engine, seed: u64_t) -> c_int;
+    fn af_random_engine_get_seed(seed: *mut u64_t, engine: af_random_engine) -> c_int;
+    fn af_release_random_engine(engine: af_random_engine) -> c_int;
+
+    fn af_get_default_random_engine(engine: *mut af_random_engine) -> c_int;
+    fn af_set_default_random_engine_type(rtype: c_uint) -> c_int;
+
+    fn af_random_uniform(
+        out: *mut af_array,
+        ndims: c_uint,
+        dims: *const dim_t,
+        aftype: c_uint,
+        engine: af_random_engine,
+    ) -> c_int;
+    fn af_random_normal(
+        out: *mut af_array,
+        ndims: c_uint,
+        dims: *const dim_t,
+        aftype: c_uint,
+        engine: af_random_engine,
+    ) -> c_int;
+}
+
+/// Set seed for random number generation
+pub fn set_seed(seed: u64) {
+    unsafe {
+        let err_val = af_set_seed(seed as u64_t);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Get the seed of random number generator
+pub fn get_seed() -> u64 {
+    let mut ret_val: u64 = 0;
+    unsafe {
+        let err_val = af_get_seed(&mut ret_val as *mut u64_t);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    ret_val
+}
+
+macro_rules! data_gen_def {
+    [$doc_str: expr, $fn_name:ident, $ffi_name: ident, $($type_trait: ident),+] => (
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `dims` is the output dimensions
+        ///
+        ///# Return Values
+        ///
+        /// An Array with random values.
+        pub fn $fn_name<T>(dims: Dim4) -> Array<T>
+        where $( T: $type_trait, )* {
+            let aftype = T::get_af_dtype();
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(&mut temp as *mut af_array,
+                                        dims.ndims() as c_uint, dims.get().as_ptr() as *const dim_t,
+                                        aftype as c_uint);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    )
+}
+
+data_gen_def!(
+    "Create random numbers from uniform distribution",
+    randu,
+    af_randu,
+    HasAfEnum
+);
+data_gen_def!(
+    "Create random numbers from normal distribution",
+    randn,
+    af_randn,
+    HasAfEnum,
+    FloatingPoint
+);
+
+/// Random number generator engine
+///
+/// This is a wrapper for ArrayFire's native random number generator engine.
+///
+/// ## Sharing Across Threads
+///
+/// While sharing this object with other threads, there is no need to wrap
+/// this in an Arc object unless only one such object is required to exist.
+/// The reason being that ArrayFire's internal details that are pointed to
+/// by the RandoMEngine handle are appropriately reference counted in thread safe
+/// manner. However, if you need to modify RandomEngine object, then please do wrap
+/// the object using a Mutex or Read-Write lock.
+pub struct RandomEngine {
+    handle: af_random_engine,
+}
+
+unsafe impl Send for RandomEngine {}
+
+/// Used for creating RandomEngine object from native resource id
+impl From<af_random_engine> for RandomEngine {
+    fn from(t: af_random_engine) -> Self {
+        Self { handle: t }
+    }
+}
+
+impl RandomEngine {
+    /// Create a new random engine object
+    ///
+    /// # Parameters
+    ///
+    /// - `rengine` can be value of [RandomEngineType](./enum.RandomEngineType.html) enum.
+    /// - `seed` is the initial seed value
+    ///
+    /// # Return Values
+    ///
+    /// A object of type RandomEngine
+    pub fn new(rengine: RandomEngineType, seed: Option<u64>) -> Self {
+        unsafe {
+            let mut temp: af_random_engine = std::ptr::null_mut();
+            let err_val = af_create_random_engine(
+                &mut temp as *mut af_random_engine,
+                rengine as c_uint,
+                match seed {
+                    Some(s) => s,
+                    None => 0,
+                } as u64_t,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+            RandomEngine { handle: temp }
+        }
+    }
+
+    /// Get random engine type
+    pub fn get_type(&self) -> RandomEngineType {
+        let mut temp: u32 = 0;
+        unsafe {
+            let err_val = af_random_engine_get_type(&mut temp as *mut c_uint, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+        RandomEngineType::from(temp)
+    }
+
+    /// Get random engine type
+    pub fn set_type(&mut self, engine_type: RandomEngineType) {
+        unsafe {
+            let err_val = af_random_engine_set_type(
+                &mut self.handle as *mut af_random_engine,
+                engine_type as c_uint,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set seed for random engine
+    pub fn set_seed(&mut self, seed: u64) {
+        unsafe {
+            let err_val =
+                af_random_engine_set_seed(&mut self.handle as *mut af_random_engine, seed as u64_t);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Get seed of the random engine
+    pub fn get_seed(&self) -> u64 {
+        let mut seed: u64 = 0;
+        unsafe {
+            let err_val = af_random_engine_get_seed(&mut seed as *mut u64_t, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+        seed
+    }
+
+    /// Returns the native FFI handle for Rust object `RandomEngine`
+    pub unsafe fn get(&self) -> af_random_engine {
+        self.handle
+    }
+}
+
+/// Increment reference count of RandomEngine's native resource
+impl Clone for RandomEngine {
+    fn clone(&self) -> Self {
+        unsafe {
+            let mut temp: af_random_engine = std::ptr::null_mut();
+            let err_val = af_retain_random_engine(&mut temp as *mut af_random_engine, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            RandomEngine::from(temp)
+        }
+    }
+}
+
+/// Free RandomEngine's native resource
+impl Drop for RandomEngine {
+    fn drop(&mut self) {
+        unsafe {
+            let err_val = af_release_random_engine(self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+}
+
+#[cfg(feature = "afserde")]
+mod afserde {
+    // Reimport required from super scope
+    use super::{RandomEngine, RandomEngineType};
+
+    use serde::de::Deserializer;
+    use serde::ser::Serializer;
+    use serde::{Deserialize, Serialize};
+
+    #[derive(Debug, Serialize, Deserialize)]
+    struct RandEngine {
+        engine_type: RandomEngineType,
+        seed: u64,
+    }
+
+    /// Serialize Implementation of Array
+    impl Serialize for RandomEngine {
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            let r = RandEngine {
+                engine_type: self.get_type(),
+                seed: self.get_seed(),
+            };
+            r.serialize(serializer)
+        }
+    }
+
+    /// Deserialize Implementation of Array
+    #[cfg(feature = "afserde")]
+    impl<'de> Deserialize<'de> for RandomEngine {
+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+        where
+            D: Deserializer<'de>,
+        {
+            match RandEngine::deserialize(deserializer) {
+                Ok(r) => Ok(RandomEngine::new(r.engine_type, Some(r.seed))),
+                Err(err) => Err(err),
+            }
+        }
+    }
+}
+
+/// Get default random engine
+pub fn get_default_random_engine() -> RandomEngine {
+    unsafe {
+        let mut temp: af_random_engine = std::ptr::null_mut();
+        let mut err_val = af_get_default_random_engine(&mut temp as *mut af_random_engine);
+        HANDLE_ERROR(AfError::from(err_val));
+        let mut handle: af_random_engine = std::ptr::null_mut();
+        err_val = af_retain_random_engine(&mut handle as *mut af_random_engine, temp);
+        HANDLE_ERROR(AfError::from(err_val));
+        RandomEngine { handle: handle }
+    }
+}
+
+/// Set the random engine type for default random number generator
+///
+/// # Parameters
+///
+/// - `rtype` can take one of the values of enum [RandomEngineType](./enum.RandomEngineType.html)
+pub fn set_default_random_engine_type(rtype: RandomEngineType) {
+    unsafe {
+        let err_val = af_set_default_random_engine_type(rtype as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Generate array of uniform numbers using a random engine
+///
+/// # Parameters
+///
+/// - `dims` is output array dimensions
+/// - `engine` is an object of type [RandomEngine](./struct.RandomEngine.html)
+///
+/// # Return Values
+///
+/// An Array with uniform numbers generated using random engine
+pub fn random_uniform<T>(dims: Dim4, engine: &RandomEngine) -> Array<T>
+where
+    T: HasAfEnum,
+{
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_random_uniform(
+            &mut temp as *mut af_array,
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+            aftype as c_uint,
+            engine.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Generate array of normal numbers using a random engine
+///
+/// # Parameters
+///
+/// - `dims` is output array dimensions
+/// - `engine` is an object of type [RandomEngine](./struct.RandomEngine.html)
+///
+/// # Return Values
+///
+/// An Array with normal numbers generated using random engine
+pub fn random_normal<T>(dims: Dim4, engine: &RandomEngine) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_random_normal(
+            &mut temp as *mut af_array,
+            dims.ndims() as c_uint,
+            dims.get().as_ptr() as *const dim_t,
+            aftype as c_uint,
+            engine.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #[cfg(feature = "afserde")]
+    mod serde_tests {
+        use super::super::RandomEngine;
+        use crate::core::defines::RandomEngineType;
+
+        #[test]
+        #[cfg(feature = "afserde")]
+        fn random_engine_serde_bincode() {
+            let input = RandomEngine::new(RandomEngineType::THREEFRY_2X32_16, Some(2047));
+            let encoded = match bincode::serialize(&input) {
+                Ok(encoded) => encoded,
+                Err(_) => vec![],
+            };
+
+            let decoded: RandomEngine = bincode::deserialize(&encoded).unwrap();
+
+            assert_eq!(input.get_seed(), decoded.get_seed());
+            assert_eq!(input.get_type(), decoded.get_type());
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/seq.rs.html b/src/arrayfire/core/seq.rs.html new file mode 100644 index 000000000..0507eb811 --- /dev/null +++ b/src/arrayfire/core/seq.rs.html @@ -0,0 +1,197 @@ +seq.rs - source + + + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+
+use num::{One, Zero};
+
+#[cfg(feature = "afserde")]
+use serde::{Deserialize, Serialize};
+use std::default::Default;
+use std::fmt;
+
+use super::util::IndexableType;
+
+/// Sequences are used for indexing Arrays
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
+#[repr(C)]
+pub struct Seq<T: IndexableType> {
+    begin: T,
+    end: T,
+    step: T,
+}
+
+/// Default `Seq` spans all the elements along a dimension
+impl<T> Default for Seq<T>
+where
+    T: One + Zero + IndexableType,
+{
+    fn default() -> Self {
+        Self {
+            begin: One::one(),
+            end: One::one(),
+            step: Zero::zero(),
+        }
+    }
+}
+
+/// Enables use of `Seq` with `{}` format in print statements
+impl<T> fmt::Display for Seq<T>
+where
+    T: fmt::Display + IndexableType,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "[begin: {}, end: {}, step: {}]",
+            self.begin, self.end, self.step
+        )
+    }
+}
+
+impl<T> Seq<T>
+where
+    T: Copy + IndexableType,
+{
+    /// Create a `Seq` that goes from `begin` to `end` at a step size of `step`
+    pub fn new(begin: T, end: T, step: T) -> Self {
+        Self { begin, end, step }
+    }
+
+    /// Get begin index of Seq
+    pub fn begin(&self) -> T {
+        self.begin
+    }
+
+    /// Get end index of Seq
+    pub fn end(&self) -> T {
+        self.end
+    }
+
+    /// Get step size of Seq
+    pub fn step(&self) -> T {
+        self.step
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #[cfg(feature = "afserde")]
+    #[test]
+    fn seq_serde() {
+        use super::Seq;
+        use crate::seq;
+
+        let original = seq!(1:2:1);
+        let serd = match serde_json::to_string(&original) {
+            Ok(serialized_str) => serialized_str,
+            Err(e) => e.to_string(),
+        };
+
+        let deserd: Seq<i32> = serde_json::from_str(&serd).unwrap();
+        assert_eq!(deserd, original);
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/core/util.rs.html b/src/arrayfire/core/util.rs.html new file mode 100644 index 000000000..f5e3a5ced --- /dev/null +++ b/src/arrayfire/core/util.rs.html @@ -0,0 +1,1715 @@ +util.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+
+use super::defines::{
+    AfError, BinaryOp, ColorMap, ConvDomain, ConvMode, DType, InterpType, MatProp, MatchType,
+    RandomEngineType, SparseFormat,
+};
+use super::error::HANDLE_ERROR;
+
+use half::f16;
+use libc::{c_int, c_uint, c_void, size_t};
+use num::Complex;
+use std::convert::From;
+use std::mem;
+use std::ops::BitOr;
+
+/// Short type alias for Complex single precision type
+pub type c32 = Complex<f32>;
+/// Short type alias for Complex double precision type
+pub type c64 = Complex<f64>;
+/// ArrayFire FFI Type alias for libc's signed long long
+pub type dim_t = libc::c_longlong;
+/// ArrayFire FFI Type alias for libc's unsigned long long
+pub type u64_t = libc::c_ulonglong;
+/// ArrayFire FFI Type alias for libc's void*
+pub type void_ptr = *mut libc::c_void;
+
+/// ArrayFire FFI Type alias for af_array
+pub type af_array = *mut libc::c_void;
+/// ArrayFire FFI Type alias for af_event
+pub type af_event = *mut libc::c_void;
+/// ArrayFire FFI Type alias for af_indexers_t
+pub type af_index_t = *mut libc::c_void;
+/// ArrayFire FFI Type alias for af_features
+pub type af_features = *const libc::c_void;
+/// ArrayFire FFI Type alias for af_random_engine
+pub type af_random_engine = *mut libc::c_void;
+/// ArrayFire FFI Type alias for af_window
+pub type af_window = *mut libc::c_void;
+
+extern "C" {
+    fn af_get_size_of(size: *mut size_t, aftype: c_uint) -> c_int;
+    fn af_alloc_host(ptr: *mut *const c_void, bytes: dim_t) -> c_int;
+    fn af_free_host(ptr: *mut c_void) -> c_int;
+}
+
+/// Get size, in bytes, of the arrayfire native type
+pub fn get_size(value: DType) -> usize {
+    unsafe {
+        let mut ret_val: usize = 0;
+        let err_val = af_get_size_of(&mut ret_val as *mut size_t, value as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        ret_val
+    }
+}
+
+/// Allocates space using Arrayfire allocator in host memory
+pub fn alloc_host<T>(elements: usize, _type: DType) -> *const T {
+    let ptr: *const T = ::std::ptr::null();
+    let bytes = (elements * get_size(_type)) as dim_t;
+    unsafe {
+        let err_val = af_alloc_host(&mut (ptr as *const c_void), bytes);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    ptr
+}
+
+/// Frees memory allocated by Arrayfire allocator in host memory
+pub fn free_host<T>(ptr: *mut T) {
+    unsafe {
+        let err_val = af_free_host(ptr as *mut c_void);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+impl From<i32> for AfError {
+    fn from(t: i32) -> Self {
+        assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for DType {
+    fn from(t: u32) -> Self {
+        assert!(DType::F32 as u32 <= t && t <= DType::U64 as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for InterpType {
+    fn from(t: u32) -> Self {
+        assert!(InterpType::NEAREST as u32 <= t && t <= InterpType::BICUBIC_SPLINE as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for ConvMode {
+    fn from(t: u32) -> Self {
+        assert!(ConvMode::DEFAULT as u32 <= t && t <= ConvMode::EXPAND as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for ConvDomain {
+    fn from(t: u32) -> Self {
+        assert!(ConvDomain::AUTO as u32 <= t && t <= ConvDomain::FREQUENCY as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for MatchType {
+    fn from(t: u32) -> Self {
+        assert!(MatchType::SAD as u32 <= t && t <= MatchType::SHD as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for ColorMap {
+    fn from(t: u32) -> Self {
+        assert!(ColorMap::DEFAULT as u32 <= t && t <= ColorMap::BLUE as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+/// Types of the data that can be generated using ArrayFire data generation functions.
+///
+/// The trait HasAfEnum has been defined internally for the following types. We strongly suggest
+/// not to implement this trait in your program for user defined types because ArrayFire functions
+/// will only work for the following data types currently. Any such trait implementation for types
+/// other than the ones listed below will result in undefined behavior.
+///
+/// - f32
+/// - f64
+/// - num::Complex\<f32\>
+/// - num::Complex\<f64\>
+/// - bool
+/// - i32
+/// - u32
+/// - u8
+/// - i64
+/// - u64
+/// - i16
+/// - u16
+///
+pub trait HasAfEnum {
+    /// This type alias points to `Self` always.
+    type InType: HasAfEnum;
+    /// This type alias points to the data type used to hold real part of a
+    /// complex number. For real valued numbers, this points to `Self`.
+    type BaseType: HasAfEnum;
+    /// This type alias points to `f32` for all 32 bit size types and `f64` for
+    /// larger 64-bit size types.
+    type AbsOutType: HasAfEnum;
+    /// This type alias points to `f64`/`f32` for floating point types and
+    /// `Self` otherwise.
+    type ArgOutType: HasAfEnum;
+    /// This type alias is used to define the output Array type for unary
+    /// operations. It points to `Self` for floating point types, either
+    /// real or complex. It points to `f32` for rest of the input types.
+    type UnaryOutType: HasAfEnum;
+    /// This type alias points to complex type created from a given input type.
+    /// This alias always points to either `std::Complex<f32>` or `std::Complex<f64>`
+    type ComplexOutType;
+    /// This type alias points to a data type that can store the mean value for
+    /// a given input type. This alias points to `f32`/`Complex<f32>` for all 32
+    /// bit size types and `f64`/`Complex<f64>` for larger 64-bit size types.
+    type MeanOutType: HasAfEnum;
+    /// This type alias points to a data type that can store the result of
+    /// aggregation of set of values for a given input type. Aggregate type
+    /// alias points to below types for given input types:
+    /// - `Self` for input types: `Complex<64>`, `Complex<f32>`, `f64`, `f32`, `i64`, `u64`
+    /// - `u32` for input types: `bool`
+    /// - `u32` for input types: `u8`
+    /// - `i32` for input types: `i16`
+    /// - `u32` for input types: `u16`
+    /// - `i32` for input types: `i32`
+    /// - `u32` for input types: `u32`
+    type AggregateOutType: HasAfEnum;
+    /// This type is different for b8 input type
+    type ProductOutType: HasAfEnum;
+    /// This type alias points to the output type for given input type of
+    /// sobel filter operation. Sobel filter output alias points to below
+    /// types for given input types:
+    /// - `f32` for input types: `Complex<f32>`, `f32`
+    /// - `f64` for input types: `Complex<f64>`, `f64`
+    /// - `i32` for input types: `bool`, `u8`, `i16`, `u16`, `i32`, `u32`
+    /// - `i64` for input types: `i64`, `u64`
+    type SobelOutType: HasAfEnum;
+
+    /// Return trait implmentors corresponding [DType](./enum.DType.html)
+    fn get_af_dtype() -> DType;
+}
+
+impl HasAfEnum for Complex<f32> {
+    type InType = Self;
+    type BaseType = f32;
+    type AbsOutType = f32;
+    type ArgOutType = f32;
+    type UnaryOutType = Self;
+    type ComplexOutType = Self;
+    type MeanOutType = Self;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = Self;
+
+    fn get_af_dtype() -> DType {
+        DType::C32
+    }
+}
+impl HasAfEnum for Complex<f64> {
+    type InType = Self;
+    type BaseType = f64;
+    type AbsOutType = f64;
+    type ArgOutType = f64;
+    type UnaryOutType = Self;
+    type ComplexOutType = Self;
+    type MeanOutType = Self;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = Self;
+
+    fn get_af_dtype() -> DType {
+        DType::C64
+    }
+}
+impl HasAfEnum for f32 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = f32;
+    type UnaryOutType = Self;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = Self;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = Self;
+
+    fn get_af_dtype() -> DType {
+        DType::F32
+    }
+}
+impl HasAfEnum for f64 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f64;
+    type ArgOutType = f64;
+    type UnaryOutType = Self;
+    type ComplexOutType = Complex<f64>;
+    type MeanOutType = Self;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = Self;
+
+    fn get_af_dtype() -> DType {
+        DType::F64
+    }
+}
+impl HasAfEnum for bool {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = bool;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = u32;
+    type ProductOutType = bool;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::B8
+    }
+}
+impl HasAfEnum for u8 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = u8;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = u32;
+    type ProductOutType = u32;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::U8
+    }
+}
+impl HasAfEnum for i16 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = i16;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = i32;
+    type ProductOutType = i32;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::S16
+    }
+}
+impl HasAfEnum for u16 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = u16;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = u32;
+    type ProductOutType = u32;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::U16
+    }
+}
+impl HasAfEnum for f16 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = Self;
+    type ArgOutType = Self;
+    type UnaryOutType = Self;
+    type ComplexOutType = Complex<f16>;
+    type MeanOutType = Self;
+    type AggregateOutType = f32;
+    type ProductOutType = f32;
+    type SobelOutType = Self;
+
+    fn get_af_dtype() -> DType {
+        DType::F16
+    }
+}
+impl HasAfEnum for i32 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = i32;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = i32;
+    type ProductOutType = i32;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::S32
+    }
+}
+impl HasAfEnum for u32 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f32;
+    type ArgOutType = u32;
+    type UnaryOutType = f32;
+    type ComplexOutType = Complex<f32>;
+    type MeanOutType = f32;
+    type AggregateOutType = u32;
+    type ProductOutType = u32;
+    type SobelOutType = i32;
+
+    fn get_af_dtype() -> DType {
+        DType::U32
+    }
+}
+impl HasAfEnum for i64 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f64;
+    type ArgOutType = i64;
+    type UnaryOutType = f64;
+    type ComplexOutType = Complex<f64>;
+    type MeanOutType = f64;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = i64;
+
+    fn get_af_dtype() -> DType {
+        DType::S64
+    }
+}
+impl HasAfEnum for u64 {
+    type InType = Self;
+    type BaseType = Self;
+    type AbsOutType = f64;
+    type ArgOutType = u64;
+    type UnaryOutType = f64;
+    type ComplexOutType = Complex<f64>;
+    type MeanOutType = f64;
+    type AggregateOutType = Self;
+    type ProductOutType = Self;
+    type SobelOutType = i64;
+
+    fn get_af_dtype() -> DType {
+        DType::U64
+    }
+}
+
+impl From<u32> for SparseFormat {
+    fn from(t: u32) -> Self {
+        assert!(SparseFormat::DENSE as u32 <= t && t <= SparseFormat::COO as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for BinaryOp {
+    fn from(t: u32) -> Self {
+        assert!(BinaryOp::ADD as u32 <= t && t <= BinaryOp::MAX as u32);
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl From<u32> for RandomEngineType {
+    fn from(t: u32) -> Self {
+        assert!(
+            RandomEngineType::PHILOX_4X32_10 as u32 <= t
+                && t <= RandomEngineType::MERSENNE_GP11213 as u32
+        );
+        unsafe { mem::transmute(t) }
+    }
+}
+
+/// This is an internal trait defined and implemented by ArrayFire
+/// create for rust's built-in types to figure out the data type
+/// binary operation's results.
+pub trait ImplicitPromote<RHS>: HasAfEnum {
+    /// This type alias points to the type of the result obtained
+    /// by performing a given binary option on given type and `RHS`.
+    type Output: HasAfEnum;
+}
+
+impl<T> ImplicitPromote<T> for T
+where
+    T: HasAfEnum,
+{
+    type Output = T;
+}
+
+macro_rules! implicit {
+    [$implType: ident, $rhsType: ident => $outType: ident] => (
+        impl ImplicitPromote< $rhsType > for $implType {
+            type Output = $outType;
+        }
+    )
+}
+
+//
+//implicit(implementation type, RHS type, output type)
+//
+
+//LHS is Complex double
+implicit!(c64, c32 => c64);
+implicit!(c64, f64       => c64);
+implicit!(c64, f32       => c64);
+implicit!(c64, i64       => c64);
+implicit!(c64, u64       => c64);
+implicit!(c64, i32       => c64);
+implicit!(c64, u32       => c64);
+implicit!(c64, i16       => c64);
+implicit!(c64, u16       => c64);
+implicit!(c64, bool      => c64);
+implicit!(c64, u8        => c64);
+
+//LHS is Complex float
+implicit!(c32, c64 => c64);
+implicit!(c32, f64       => c64);
+implicit!(c32, f32       => c32);
+implicit!(c32, i64       => c32);
+implicit!(c32, u64       => c32);
+implicit!(c32, i32       => c32);
+implicit!(c32, u32       => c32);
+implicit!(c32, i16       => c32);
+implicit!(c32, u16       => c32);
+implicit!(c32, bool      => c32);
+implicit!(c32, u8        => c32);
+
+//LHS is 64-bit floating point
+implicit!(f64, c64 => c64);
+implicit!(f64, c32 => c64);
+implicit!(f64, f32       =>       f64);
+implicit!(f64, i64       =>       f64);
+implicit!(f64, u64       =>       f64);
+implicit!(f64, i32       =>       f64);
+implicit!(f64, u32       =>       f64);
+implicit!(f64, i16       =>       f64);
+implicit!(f64, u16       =>       f64);
+implicit!(f64, bool      =>       f64);
+implicit!(f64, u8        =>       f64);
+
+//LHS is 32-bit floating point
+implicit!(f32, c64 => c64);
+implicit!(f32, c32 => c32);
+implicit!(f32, f64       =>       f64);
+implicit!(f32, i64       =>       f32);
+implicit!(f32, u64       =>       f32);
+implicit!(f32, i32       =>       f32);
+implicit!(f32, u32       =>       f32);
+implicit!(f32, i16       =>       f32);
+implicit!(f32, u16       =>       f32);
+implicit!(f32, bool      =>       f32);
+implicit!(f32, u8        =>       f32);
+
+//LHS is 64-bit signed integer
+implicit!(i64, c64 => c64);
+implicit!(i64, c32 => c32);
+implicit!(i64, f64       =>       f64);
+implicit!(i64, f32       =>       f32);
+implicit!(i64, u64       =>       u64);
+implicit!(i64, i32       =>       i64);
+implicit!(i64, u32       =>       i64);
+implicit!(i64, i16       =>       i64);
+implicit!(i64, u16       =>       i64);
+implicit!(i64, bool      =>       i64);
+implicit!(i64, u8        =>       i64);
+
+//LHS is 64-bit unsigned integer
+implicit!(u64, c64 => c64);
+implicit!(u64, c32 => c32);
+implicit!(u64, f64       =>       f64);
+implicit!(u64, f32       =>       f32);
+implicit!(u64, i64       =>       u64);
+implicit!(u64, i32       =>       u64);
+implicit!(u64, u32       =>       u64);
+implicit!(u64, i16       =>       u64);
+implicit!(u64, u16       =>       u64);
+implicit!(u64, bool      =>       u64);
+implicit!(u64, u8        =>       u64);
+
+//LHS is 32-bit signed integer
+implicit!(i32, c64 => c64);
+implicit!(i32, c32 => c32);
+implicit!(i32, f64       =>       f64);
+implicit!(i32, f32       =>       f32);
+implicit!(i32, i64       =>       i64);
+implicit!(i32, u64       =>       u64);
+implicit!(i32, u32       =>       u32);
+implicit!(i32, i16       =>       i32);
+implicit!(i32, u16       =>       i32);
+implicit!(i32, bool      =>       i32);
+implicit!(i32, u8        =>       i32);
+
+//LHS is 32-bit unsigned integer
+implicit!(u32, c64 => c64);
+implicit!(u32, c32 => c32);
+implicit!(u32, f64       =>       f64);
+implicit!(u32, f32       =>       f32);
+implicit!(u32, i64       =>       i64);
+implicit!(u32, u64       =>       u64);
+implicit!(u32, i32       =>       u32);
+implicit!(u32, i16       =>       u32);
+implicit!(u32, u16       =>       u32);
+implicit!(u32, bool      =>       u32);
+implicit!(u32, u8        =>       u32);
+
+//LHS is 16-bit signed integer
+implicit!(i16, c64 => c64);
+implicit!(i16, c32 => c32);
+implicit!(i16, f64       =>       f64);
+implicit!(i16, f32       =>       f32);
+implicit!(i16, i64       =>       i64);
+implicit!(i16, u64       =>       u64);
+implicit!(i16, i32       =>       i32);
+implicit!(i16, u32       =>       u32);
+implicit!(i16, u16       =>       u16);
+implicit!(i16, bool      =>       u16);
+implicit!(i16, u8        =>       u16);
+
+//LHS is 16-bit unsigned integer
+implicit!(u16, c64 => c64);
+implicit!(u16, c32 => c32);
+implicit!(u16, f64       =>       f64);
+implicit!(u16, f32       =>       f32);
+implicit!(u16, i64       =>       i64);
+implicit!(u16, u64       =>       u64);
+implicit!(u16, i32       =>       i32);
+implicit!(u16, u32       =>       u32);
+implicit!(u16, i16       =>       u16);
+implicit!(u16, bool      =>       u16);
+implicit!(u16, u8        =>       u16);
+
+//LHS is 8-bit unsigned integer
+implicit!(u8, c64 => c64);
+implicit!(u8, c32 => c32);
+implicit!(u8, f64       =>       f64);
+implicit!(u8, f32       =>       f32);
+implicit!(u8, i64       =>       i64);
+implicit!(u8, u64       =>       u64);
+implicit!(u8, i32       =>       i32);
+implicit!(u8, u32       =>       u32);
+implicit!(u8, i16       =>       i16);
+implicit!(u8, u16       =>       u16);
+implicit!(u8, bool      =>        u8);
+
+//LHS is bool(af::s8)
+implicit!(bool, c64 => c64);
+implicit!(bool, c32 => c32);
+implicit!(bool, f64       =>       f64);
+implicit!(bool, f32       =>       f32);
+implicit!(bool, i64       =>       i64);
+implicit!(bool, u64       =>       u64);
+implicit!(bool, i32       =>       i32);
+implicit!(bool, u32       =>       u32);
+implicit!(bool, i16       =>       i16);
+implicit!(bool, u16       =>       u16);
+implicit!(bool, u8        =>        u8);
+
+///Trait qualifier to accept either real or complex typed data
+pub trait FloatingPoint: HasAfEnum {
+    /// Use to check if trait implementor is real number
+    fn is_real() -> bool {
+        false
+    }
+    /// Use to check if trait implementor is complex number
+    fn is_complex() -> bool {
+        false
+    }
+}
+
+impl FloatingPoint for Complex<f64> {
+    fn is_complex() -> bool {
+        true
+    }
+}
+impl FloatingPoint for Complex<f32> {
+    fn is_complex() -> bool {
+        true
+    }
+}
+impl FloatingPoint for f64 {
+    fn is_real() -> bool {
+        true
+    }
+}
+impl FloatingPoint for f32 {
+    fn is_real() -> bool {
+        true
+    }
+}
+
+///Trait qualifier to accept real data(numbers)
+pub trait RealFloating: HasAfEnum {}
+
+impl RealFloating for f64 {}
+impl RealFloating for f32 {}
+
+///Trait qualifier to accept complex data(numbers)
+pub trait ComplexFloating: HasAfEnum {}
+
+impl ComplexFloating for c64 {}
+impl ComplexFloating for c32 {}
+
+///Trait qualifier indicating it can hold real numbers only
+pub trait RealNumber: HasAfEnum {}
+
+impl RealNumber for f64 {}
+impl RealNumber for f32 {}
+impl RealNumber for i32 {}
+impl RealNumber for u32 {}
+impl RealNumber for i16 {}
+impl RealNumber for u16 {}
+impl RealNumber for u8 {}
+impl RealNumber for bool {}
+impl RealNumber for u64 {}
+impl RealNumber for i64 {}
+
+///Trait qualifier for the type of Arrays accepted by scan operations
+pub trait Scanable: HasAfEnum {}
+
+impl Scanable for i32 {}
+impl Scanable for u32 {}
+impl Scanable for u64 {}
+impl Scanable for i64 {}
+
+/// Trait qualifier for type of Array's that are accepted
+/// by native image load/save functions.
+pub trait ImageNativeType: HasAfEnum {}
+
+impl ImageNativeType for f32 {}
+impl ImageNativeType for u16 {}
+impl ImageNativeType for u8 {}
+
+/// Trait qualifier for type of Array's that are accepted
+/// by image processing functions especially filtering algorithms
+pub trait ImageFilterType: HasAfEnum {}
+
+impl ImageFilterType for f64 {}
+impl ImageFilterType for f32 {}
+impl ImageFilterType for i32 {}
+impl ImageFilterType for u32 {}
+impl ImageFilterType for i16 {}
+impl ImageFilterType for u16 {}
+impl ImageFilterType for u8 {}
+impl ImageFilterType for bool {}
+
+// TODO Rust haven't stabilized trait aliases yet
+/// Trait qualifier for given type indicating conversion capability between
+/// grayscale and RGB triplets of data
+pub trait GrayRGBConvertible: HasAfEnum {}
+
+impl GrayRGBConvertible for f64 {}
+impl GrayRGBConvertible for f32 {}
+impl GrayRGBConvertible for i32 {}
+impl GrayRGBConvertible for u32 {}
+impl GrayRGBConvertible for i16 {}
+impl GrayRGBConvertible for u16 {}
+impl GrayRGBConvertible for u8 {}
+
+// TODO Rust haven't stabilized trait aliases yet
+/// Trait qualifier for given type indicating computability of Moments
+pub trait MomentsComputable: HasAfEnum {}
+
+impl MomentsComputable for f64 {}
+impl MomentsComputable for f32 {}
+impl MomentsComputable for i32 {}
+impl MomentsComputable for u32 {}
+impl MomentsComputable for i16 {}
+impl MomentsComputable for u16 {}
+impl MomentsComputable for u8 {}
+
+// TODO Rust haven't stabilized trait aliases yet
+/// Trait qualifier for given type indicating computability of Median
+pub trait MedianComputable: HasAfEnum {}
+
+impl MedianComputable for f64 {}
+impl MedianComputable for f32 {}
+impl MedianComputable for i32 {}
+impl MedianComputable for u32 {}
+impl MedianComputable for i16 {}
+impl MedianComputable for u16 {}
+impl MedianComputable for u8 {}
+
+// TODO Rust haven't stabilized trait aliases yet
+/// Trait qualifier for given type indicating if edge calculations such as
+/// derivates etc. can be performed
+pub trait EdgeComputable: HasAfEnum {}
+
+impl EdgeComputable for f64 {}
+impl EdgeComputable for f32 {}
+impl EdgeComputable for i32 {}
+impl EdgeComputable for u32 {}
+impl EdgeComputable for i16 {}
+impl EdgeComputable for u16 {}
+impl EdgeComputable for u8 {}
+
+/// Trait qualifier for given type indicating computability of covariance
+pub trait CovarianceComputable: HasAfEnum {}
+
+impl CovarianceComputable for f64 {}
+impl CovarianceComputable for f32 {}
+impl CovarianceComputable for i32 {}
+impl CovarianceComputable for u32 {}
+impl CovarianceComputable for i16 {}
+impl CovarianceComputable for u16 {}
+impl CovarianceComputable for u8 {}
+impl CovarianceComputable for u64 {}
+impl CovarianceComputable for i64 {}
+
+/// Trait qualifier for confidence connected components input
+pub trait ConfidenceCCInput: HasAfEnum {}
+
+impl ConfidenceCCInput for f32 {}
+impl ConfidenceCCInput for u32 {}
+impl ConfidenceCCInput for u16 {}
+impl ConfidenceCCInput for u8 {}
+
+/// Trait qualifier for confidence connected components input
+pub trait DeconvInput: HasAfEnum {}
+
+impl DeconvInput for f32 {}
+impl DeconvInput for i16 {}
+impl DeconvInput for u16 {}
+impl DeconvInput for u8 {}
+
+/// Trait qualifier for Reduction Key type
+pub trait ReduceByKeyInput: HasAfEnum {}
+
+impl ReduceByKeyInput for i32 {}
+impl ReduceByKeyInput for u32 {}
+
+impl From<u32> for MatProp {
+    fn from(t: u32) -> Self {
+        unsafe { mem::transmute(t) }
+    }
+}
+
+impl BitOr for MatProp {
+    type Output = Self;
+
+    fn bitor(self, rhs: Self) -> Self {
+        Self::from(self as u32 | rhs as u32)
+    }
+}
+
+/// Trait to convert reduction's scalar output to appropriate output type
+///
+/// This is an internal trait and ideally of no use to user usecases.
+pub trait Fromf64 {
+    /// Convert to target type from a double precision value
+    fn fromf64(value: f64) -> Self;
+}
+
+#[rustfmt::skip]
+impl Fromf64 for usize{ fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for f64  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for u64  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for i64  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for f32  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for u32  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for i32  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for u16  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for i16  { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for u8   { fn fromf64(value: f64) -> Self { value as Self }}
+#[rustfmt::skip]
+impl Fromf64 for bool { fn fromf64(value: f64) -> Self { value > 0.0   }}
+
+///Trait qualifier for the type of Arrays accepted by scan operations
+pub trait IndexableType: HasAfEnum {}
+
+impl IndexableType for f64 {}
+impl IndexableType for i64 {}
+impl IndexableType for u64 {}
+impl IndexableType for f32 {}
+impl IndexableType for i32 {}
+impl IndexableType for u32 {}
+impl IndexableType for i16 {}
+impl IndexableType for u16 {}
+impl IndexableType for u8 {}
+
+/// Trait qualifier for given type indicating computability of covariance
+pub trait IntegralType {}
+
+impl IntegralType for i64 {}
+impl IntegralType for u64 {}
+impl IntegralType for i32 {}
+impl IntegralType for u32 {}
+impl IntegralType for i16 {}
+impl IntegralType for u16 {}
+impl IntegralType for u8 {}
+impl IntegralType for bool {}
+
+
\ No newline at end of file diff --git a/src/arrayfire/graphics/mod.rs.html b/src/arrayfire/graphics/mod.rs.html new file mode 100644 index 000000000..3077db201 --- /dev/null +++ b/src/arrayfire/graphics/mod.rs.html @@ -0,0 +1,2071 @@ +mod.rs - source + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+
+use super::core::{
+    af_array, af_window, AfError, Array, ColorMap, HasAfEnum, MarkerType, HANDLE_ERROR,
+};
+
+use libc::{c_char, c_double, c_float, c_int, c_uint};
+use std::ffi::CString;
+use std::ptr;
+
+/// Represents a sub-view of Window
+///
+/// This struct is used in conjunction with [Window](./struct.Window.html) in multiview
+/// mode to render multiple targets to sub-regions of a given window.
+///
+#[repr(C)]
+struct af_cell {
+    pub row: c_int,
+    pub col: c_int,
+    pub title: *const c_char,
+    pub cmap: c_uint,
+}
+
+extern "C" {
+    fn af_create_window(out: *mut af_window, w: c_int, h: c_int, title: *const c_char) -> c_int;
+
+    fn af_set_position(wnd: af_window, x: c_uint, y: c_uint) -> c_int;
+    fn af_set_title(wnd: af_window, title: *const c_char) -> c_int;
+    fn af_set_size(wnd: af_window, w: c_uint, h: c_uint) -> c_int;
+    fn af_set_visibility(wnd: af_window, is_visible: bool) -> c_int;
+
+    fn af_set_axes_titles(
+        wnd: af_window,
+        xtitle: *const c_char,
+        ytitle: *const c_char,
+        ztitle: *const c_char,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_set_axes_label_format(
+        wnd: af_window,
+        xformat: *const c_char,
+        yformat: *const c_char,
+        zformat: *const c_char,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_set_axes_limits_compute(
+        wnd: af_window,
+        x: af_array,
+        y: af_array,
+        z: af_array,
+        exact: bool,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_set_axes_limits_2d(
+        wnd: af_window,
+        xmin: c_float,
+        xmax: c_float,
+        ymin: c_float,
+        ymax: c_float,
+        exact: bool,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_set_axes_limits_3d(
+        wnd: af_window,
+        xmin: c_float,
+        xmax: c_float,
+        ymin: c_float,
+        ymax: c_float,
+        zmin: c_float,
+        zmax: c_float,
+        exact: bool,
+        props: *const af_cell,
+    ) -> c_int;
+
+    fn af_draw_image(wnd: af_window, arr: af_array, props: *const af_cell) -> c_int;
+    fn af_draw_hist(
+        wnd: af_window,
+        x: af_array,
+        minval: c_double,
+        maxval: c_double,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_surface(
+        wnd: af_window,
+        xvals: af_array,
+        yvals: af_array,
+        S: af_array,
+        props: *const af_cell,
+    ) -> c_int;
+
+    fn af_draw_plot_2d(wnd: af_window, x: af_array, y: af_array, props: *const af_cell) -> c_int;
+    fn af_draw_plot_3d(
+        wnd: af_window,
+        x: af_array,
+        y: af_array,
+        z: af_array,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_plot_nd(wnd: af_window, P: af_array, props: *const af_cell) -> c_int;
+
+    fn af_draw_scatter_2d(
+        wnd: af_window,
+        x: af_array,
+        y: af_array,
+        marker: c_uint,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_scatter_3d(
+        wnd: af_window,
+        x: af_array,
+        y: af_array,
+        z: af_array,
+        marker: c_uint,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_scatter_nd(
+        wnd: af_window,
+        P: af_array,
+        marker: c_uint,
+        props: *const af_cell,
+    ) -> c_int;
+
+    fn af_draw_vector_field_2d(
+        wnd: af_window,
+        xpnts: af_array,
+        ypnts: af_array,
+        xdirs: af_array,
+        ydirs: af_array,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_vector_field_3d(
+        wnd: af_window,
+        xpnts: af_array,
+        ypnts: af_array,
+        xdirs: af_array,
+        ydirs: af_array,
+        zdirs: af_array,
+        zdirs: af_array,
+        props: *const af_cell,
+    ) -> c_int;
+    fn af_draw_vector_field_nd(
+        wnd: af_window,
+        pnts: af_array,
+        dirs: af_array,
+        props: *const af_cell,
+    ) -> c_int;
+
+    fn af_grid(wnd: af_window, rows: c_int, cols: c_int) -> c_int;
+    fn af_show(wnd: af_window) -> c_int;
+    fn af_is_window_closed(out: *mut bool, wnd: af_window) -> c_int;
+    fn af_destroy_window(wnd: af_window) -> c_int;
+}
+
+/// Used to render [Array](./struct.Array.html) objects
+///
+/// The renderings can be either plots, histograms or simply just image displays.
+/// A single window can also display multiple of the above renderings at the same time, which
+/// is known as multiview mode. An example of that is given below.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// use arrayfire::{histogram, load_image, Window};
+/// let mut wnd = Window::new(1280, 720, String::from("Image Histogram"));
+/// let img = load_image::<f32>("Path to image".to_string(), true/*If color image, 'false' otherwise*/);
+/// let hst = histogram(&img, 256, 0 as f64, 255 as f64);
+///
+/// loop {
+///     wnd.grid(2, 1);
+///
+///     wnd.set_view(0, 0);
+///     wnd.draw_image(&img, Some("Input Image".to_string()));
+///
+///     wnd.set_view(1, 0);
+///     wnd.draw_hist(&hst, 0.0, 255.0, Some("Input Image Histogram".to_string()));
+///
+///     wnd.show();
+///
+///     if wnd.is_closed() == true { break; }
+/// }
+/// ```
+#[derive(Clone)]
+pub struct Window {
+    handle: af_window,
+    row: i32,
+    col: i32,
+    cmap: ColorMap,
+}
+
+impl Drop for Window {
+    fn drop(&mut self) {
+        unsafe {
+            let err_val = af_destroy_window(self.handle);
+            match err_val {
+                0 => (),
+                _ => panic!(
+                    "Window object destruction failed with error code: {}",
+                    err_val
+                ),
+            }
+        }
+    }
+}
+
+impl Window {
+    /// Creates new Window object
+    ///
+    /// # Parameters
+    ///
+    /// - `width` is width of the window
+    /// - `height` is the height of window
+    /// - `title` is the string displayed on window title bar
+    ///
+    /// # Return Values
+    ///
+    /// Window Object
+    #[allow(clippy::match_wild_err_arm)]
+    pub fn new(width: i32, height: i32, title: String) -> Self {
+        unsafe {
+            let cstr_ret = CString::new(title);
+            match cstr_ret {
+                Ok(cstr) => {
+                    let mut temp: af_window = std::ptr::null_mut();
+                    let err_val =
+                        af_create_window(&mut temp as *mut af_window, width, height, cstr.as_ptr());
+                    HANDLE_ERROR(AfError::from(err_val));
+                    Window {
+                        handle: temp,
+                        row: -1,
+                        col: -1,
+                        cmap: ColorMap::DEFAULT,
+                    }
+                }
+                Err(_) => {
+                    panic!("String creation failed while prepping params for window creation.")
+                }
+            }
+        }
+    }
+
+    /// Set window starting position on the screen
+    ///
+    /// # Parameters
+    ///
+    /// - `x` is the horiontal coordinate where window is to be placed
+    /// - `y` is the vertical coordinate where window is to be placed
+    pub fn set_position(&self, x: u32, y: u32) {
+        unsafe {
+            let err_val = af_set_position(self.handle, x, y);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set window title
+    ///
+    /// # Parameters
+    ///
+    /// - `title` is the string to be displayed on window title bar
+    pub fn set_title(&self, title: String) {
+        unsafe {
+            let cstr_ret = CString::new(title);
+            match cstr_ret {
+                Ok(cstr) => {
+                    let err_val = af_set_title(self.handle, cstr.as_ptr());
+                    HANDLE_ERROR(AfError::from(err_val));
+                }
+                Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL),
+            }
+        }
+    }
+
+    /// Set window visibility
+    ///
+    /// # Parameters
+    ///
+    /// - `is_visible` is a boolean indicating whether window is to be hidden or brought into focus
+    ///
+    /// # Return Values
+    ///
+    /// None
+    pub fn set_visibility(&self, is_visible: bool) {
+        unsafe {
+            let err_val = af_set_visibility(self.handle, is_visible);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set window size
+    ///
+    /// # Parameters
+    ///
+    /// - `w` is the target width of window
+    /// - `h` is the target height of window
+    pub fn set_size(&self, w: u32, h: u32) {
+        unsafe {
+            let err_val = af_set_size(self.handle, w, h);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set color map to be used for rendering image, it can take one of the values of enum
+    /// [ColorMap](./enum.ColorMap.html)
+    pub fn set_colormap(&mut self, cmap: ColorMap) {
+        self.cmap = cmap;
+    }
+
+    /// Returns true if the window close is triggered by the user
+    pub fn is_closed(&self) -> bool {
+        unsafe {
+            let mut temp: bool = true;
+            let err_val = af_is_window_closed(&mut temp as *mut bool, self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            temp
+        }
+    }
+
+    /// Setup display layout in multiview mode
+    ///
+    /// # Parameters
+    ///
+    /// - `rows` is the number of rows into which whole window is split into in multiple view mode
+    /// - `cols` is the number of cols into which whole window is split into in multiple view mode
+    pub fn grid(&self, rows: i32, cols: i32) {
+        unsafe {
+            let err_val = af_grid(self.handle, rows, cols);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Used in multiview mode to swap back buffer with front buffer to show the recently rendered
+    /// frame
+    pub fn show(&mut self) {
+        unsafe {
+            let err_val = af_show(self.handle);
+            HANDLE_ERROR(AfError::from(err_val));
+            self.row = -1;
+            self.col = -1;
+        }
+    }
+
+    /// Set the current sub-region to render
+    ///
+    /// This function is only to be used into multiview mode
+    ///
+    /// # Parameters
+    ///
+    /// - `r` is the target row id
+    /// - `c` is the target row id
+    pub fn set_view(&mut self, r: i32, c: i32) {
+        self.row = r;
+        self.col = c;
+    }
+
+    /// Set chart axes titles
+    ///
+    /// # Parameters
+    ///
+    /// - `xlabel` is x axis title
+    /// - `ylabel` is y axis title
+    /// - `zlabel` is z axis title
+    pub fn set_axes_titles(&mut self, xlabel: String, ylabel: String, zlabel: String) {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        let xstr = CString::new(xlabel).unwrap();
+        let ystr = CString::new(ylabel).unwrap();
+        let zstr = CString::new(zlabel).unwrap();
+        unsafe {
+            let err_val = af_set_axes_titles(
+                self.handle,
+                xstr.as_ptr(),
+                ystr.as_ptr(),
+                zstr.as_ptr(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set chart axes labels format
+    ///
+    /// # Parameters
+    ///
+    /// - `xlabel_format` is x axis label format. format specific is identical to C's printf format
+    /// - `ylabel_format` is y axis label format. format specific is identical to C's printf format
+    /// - `zlabel_format` is z axis label format. format specific is identical to C's printf format
+    pub fn set_axes_label_format(
+        &mut self,
+        xlabel_format: String,
+        ylabel_format: String,
+        zlabel_format: String,
+    ) {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        let xstr = CString::new(xlabel_format).unwrap();
+        let ystr = CString::new(ylabel_format).unwrap();
+        let zstr = CString::new(zlabel_format).unwrap();
+        unsafe {
+            let err_val = af_set_axes_label_format(
+                self.handle,
+                xstr.as_ptr(),
+                ystr.as_ptr(),
+                zstr.as_ptr(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set chart axes labels formats
+    ///
+    /// Axes labels use printf style format specifiers. Default specifier for the data displayed
+    /// as labels is %4.1f. This function lets the user change this label formatting to whichever
+    /// format that fits their data range and precision.
+    ///
+    /// # Parameters
+    ///
+    /// - `xlabel` is printf style format specifier for x axis
+    /// - `ylabel` is printf style format specifier for y axis
+    /// - `zlabel` is printf style format specifier for z axis
+    pub fn set_axes_label_formats(&mut self, xformat: String, yformat: String, zformat: String) {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        let xstr = CString::new(xformat).unwrap();
+        let ystr = CString::new(yformat).unwrap();
+        let zstr = CString::new(zformat).unwrap();
+        unsafe {
+            let err_val = af_set_axes_titles(
+                self.handle,
+                xstr.as_ptr(),
+                ystr.as_ptr(),
+                zstr.as_ptr(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set chart axes limits by computing limits from data
+    ///
+    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
+    /// active via set_view call
+    ///
+    /// # Parameters
+    ///
+    /// - `xrange` is set of all x values to compute min/max for x axis
+    /// - `yrange` is set of all y values to compute min/max for y axis
+    /// - `zrange` is set of all z values to compute min/max for z axis. If None is passed to
+    ///    this paramter, 2d chart limits are set.
+    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
+    ///    are to extracted. If exact is false then the most significant digit is rounded up
+    ///    to next power of 2 and the magnitude remains the same.
+    pub fn set_axes_limits_compute<T>(
+        &mut self,
+        xrange: &Array<T>,
+        yrange: &Array<T>,
+        zrange: Option<&Array<T>>,
+        exact: bool,
+    ) where
+        T: HasAfEnum,
+    {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_set_axes_limits_compute(
+                self.handle,
+                xrange.get(),
+                yrange.get(),
+                match zrange {
+                    Some(z) => z.get(),
+                    None => std::ptr::null_mut(),
+                },
+                exact,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set 2d chart axes limits
+    ///
+    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
+    /// active via set_view call
+    ///
+    /// # Parameters
+    ///
+    /// - `xmin` is minimum value on x axis
+    /// - `xmax` is maximum value on x axis
+    /// - `ymin` is minimum value on y axis
+    /// - `ymax` is maximum value on y axis
+    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
+    ///    are to extracted. If exact is false then the most significant digit is rounded up
+    ///    to next power of 2 and the magnitude remains the same.
+    pub fn set_axes_limits_2d(&mut self, xmin: f32, xmax: f32, ymin: f32, ymax: f32, exact: bool) {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_set_axes_limits_2d(
+                self.handle,
+                xmin,
+                xmax,
+                ymin,
+                ymax,
+                exact,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Set 3d chart axes limits
+    ///
+    /// In multiple view (grid) mode, setting limits will effect the chart that is currently
+    /// active via set_view call
+    ///
+    /// # Parameters
+    ///
+    /// - `xmin` is minimum value on x axis
+    /// - `xmax` is maximum value on x axis
+    /// - `ymin` is minimum value on y axis
+    /// - `ymax` is maximum value on y axis
+    /// - `zmin` is minimum value on z axis
+    /// - `zmax` is maximum value on z axis
+    /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange`
+    ///    are to extracted. If exact is false then the most significant digit is rounded up
+    ///    to next power of 2 and the magnitude remains the same.
+    #[allow(clippy::too_many_arguments)]
+    pub fn set_axes_limits_3d(
+        &mut self,
+        xmin: f32,
+        xmax: f32,
+        ymin: f32,
+        ymax: f32,
+        zmin: f32,
+        zmax: f32,
+        exact: bool,
+    ) {
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: ptr::null(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_set_axes_limits_3d(
+                self.handle,
+                xmin,
+                xmax,
+                ymin,
+                ymax,
+                zmin,
+                zmax,
+                exact,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Array as an image
+    ///
+    /// # Parameters
+    ///
+    /// - `input` image
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_image<T>(&self, input: &Array<T>, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_image(self.handle, input.get(), &cprops as *const af_cell);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given two Array's `x` and `y` as a 2d line plot
+    ///
+    /// # Parameters
+    ///
+    /// - `x` is the x coordinates of the plot
+    /// - `y` is the y coordinates of the plot
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_plot2<T>(&self, x: &Array<T>, y: &Array<T>, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_plot_2d(self.handle, x.get(), y.get(), &cprops as *const af_cell);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Array's `x`, `y` and `z` as a 3d line plot
+    ///
+    /// # Parameters
+    ///
+    /// - `x` is the x coordinates of the plot
+    /// - `y` is the y coordinates of the plot
+    /// - `z` is the z coordinates of the plot
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_plot3<T>(&self, x: &Array<T>, y: &Array<T>, z: &Array<T>, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_plot_3d(
+                self.handle,
+                x.get(),
+                y.get(),
+                z.get(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render give Arrays of points as a 3d line plot
+    ///
+    /// # Parameters
+    ///
+    /// - `points` is an Array containing list of points of plot
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_plot<T>(&self, points: &Array<T>, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_plot_nd(self.handle, points.get(), &cprops as *const af_cell);
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Array as a histogram
+    ///
+    /// # Parameters
+    ///
+    /// - `hst` is an Array containing histogram data
+    /// - `minval` is the minimum bin value of histogram
+    /// - `maxval` is the maximum bin value of histogram
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_hist<T>(&self, hst: &Array<T>, minval: f64, maxval: f64, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_hist(
+                self.handle,
+                hst.get(),
+                minval,
+                maxval,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render give Arrays as 3d surface
+    ///
+    /// # Parameters
+    ///
+    /// - `x` is the x coordinates of the surface plot
+    /// - `y` is the y coordinates of the surface plot
+    /// - `z` is the z coordinates of the surface plot
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_surface<T>(
+        &self,
+        xvals: &Array<T>,
+        yvals: &Array<T>,
+        zvals: &Array<T>,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_surface(
+                self.handle,
+                xvals.get(),
+                yvals.get(),
+                zvals.get(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Arrays as 2d scatter plot
+    ///
+    /// # Parameters
+    ///
+    /// - `xvals` is the x coordinates of the scatter plot
+    /// - `yvals` is the y coordinates of the scatter plot
+    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_scatter2<T>(
+        &self,
+        xvals: &Array<T>,
+        yvals: &Array<T>,
+        marker: MarkerType,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_scatter_2d(
+                self.handle,
+                xvals.get(),
+                yvals.get(),
+                marker as c_uint,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Arrays as 3d scatter plot
+    ///
+    /// # Parameters
+    ///
+    /// - `xvals` is the x coordinates of the scatter plot
+    /// - `yvals` is the y coordinates of the scatter plot
+    /// - `zvals` is the z coordinates of the scatter plot
+    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_scatter3<T>(
+        &self,
+        xvals: &Array<T>,
+        yvals: &Array<T>,
+        zvals: &Array<T>,
+        marker: MarkerType,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_scatter_3d(
+                self.handle,
+                xvals.get(),
+                yvals.get(),
+                zvals.get(),
+                marker as c_uint,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render give Array as 3d scatter plot
+    ///
+    /// # Parameters
+    ///
+    /// - `points` is an Array containing list of points of plot
+    /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html)
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_scatter<T>(&self, vals: &Array<T>, marker: MarkerType, title: Option<String>)
+    where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_scatter_nd(
+                self.handle,
+                vals.get(),
+                marker as c_uint,
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Arrays as 2d vector field
+    ///
+    /// # Parameters
+    ///
+    /// - `xpnts` is an Array containing list of x coordinates
+    /// - `xdirs` is an Array containing direction component of x coord
+    /// - `ypnts` is an Array containing list of y coordinates
+    /// - `ydirs` is an Array containing direction component of y coord
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_vector_field2<T>(
+        &self,
+        xpnts: &Array<T>,
+        ypnts: &Array<T>,
+        xdirs: &Array<T>,
+        ydirs: &Array<T>,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_vector_field_2d(
+                self.handle,
+                xpnts.get(),
+                ypnts.get(),
+                xdirs.get(),
+                ydirs.get(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Arrays as 3d vector field
+    ///
+    /// # Parameters
+    ///
+    /// - `xpnts` is an Array containing list of x coordinates
+    /// - `xdirs` is an Array containing direction component of x coord
+    /// - `ypnts` is an Array containing list of y coordinates
+    /// - `ydirs` is an Array containing direction component of y coord
+    /// - `zpnts` is an Array containing list of z coordinates
+    /// - `zdirs` is an Array containing direction component of z coord
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    #[allow(clippy::too_many_arguments)]
+    pub fn draw_vector_field3<T>(
+        &self,
+        xpnts: &Array<T>,
+        ypnts: &Array<T>,
+        zpnts: &Array<T>,
+        xdirs: &Array<T>,
+        ydirs: &Array<T>,
+        zdirs: &Array<T>,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_vector_field_3d(
+                self.handle,
+                xpnts.get(),
+                ypnts.get(),
+                zpnts.get(),
+                xdirs.get(),
+                ydirs.get(),
+                zdirs.get(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+
+    /// Render given Array as vector field
+    ///
+    /// # Parameters
+    ///
+    /// - `points` is an Array containing list of coordinates of vector field
+    /// - `directions` is an Array containing directions at the coordinates specified in `points`
+    /// Array.
+    /// - `title` parameter has effect only in multiview mode, where this string
+    ///    is displayed as the respective cell/view title.
+    pub fn draw_vector_field<T>(
+        &self,
+        points: &Array<T>,
+        directions: &Array<T>,
+        title: Option<String>,
+    ) where
+        T: HasAfEnum,
+    {
+        let tstr = match title {
+            Some(s) => s,
+            None => format!("Cell({},{}))", self.col, self.row),
+        };
+        let tstr = CString::new(tstr).unwrap();
+        let cprops = af_cell {
+            row: self.row,
+            col: self.col,
+            title: tstr.as_ptr(),
+            cmap: self.cmap as u32,
+        };
+        unsafe {
+            let err_val = af_draw_vector_field_nd(
+                self.handle,
+                points.get(),
+                directions.get(),
+                &cprops as *const af_cell,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/image/mod.rs.html b/src/arrayfire/image/mod.rs.html new file mode 100644 index 000000000..41f2f1d35 --- /dev/null +++ b/src/arrayfire/image/mod.rs.html @@ -0,0 +1,3841 @@ +mod.rs - source + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+
+use super::core::{
+    af_array, dim_t, AfError, Array, BorderType, CannyThresholdType, ColorSpace, ConfidenceCCInput,
+    Connectivity, DeconvInput, DiffusionEq, EdgeComputable, FloatingPoint, FluxFn,
+    GrayRGBConvertible, HasAfEnum, ImageFilterType, ImageNativeType, InterpType, InverseDeconvAlgo,
+    IterativeDeconvAlgo, MomentType, MomentsComputable, RealFloating, RealNumber, YCCStd,
+    HANDLE_ERROR,
+};
+
+use libc::{c_char, c_double, c_float, c_int, c_uint};
+use std::ffi::CString;
+
+// unused functions from image.h header
+// TODO add later when requested
+// af_load_image_memory
+// af_save_image_memory
+// af_delete_image_memory
+
+extern "C" {
+    fn af_cast(out: *mut af_array, arr: af_array, aftype: c_uint) -> c_int;
+    fn af_gradient(dx: *mut af_array, dy: *mut af_array, arr: af_array) -> c_int;
+    fn af_load_image(out: *mut af_array, filename: *const c_char, iscolor: bool) -> c_int;
+    fn af_save_image(filename: *const c_char, input: af_array) -> c_int;
+    fn af_load_image_native(out: *mut af_array, filename: *const c_char) -> c_int;
+    fn af_save_image_native(filename: *const c_char, input: af_array) -> c_int;
+
+    fn af_resize(
+        out: *mut af_array,
+        input: af_array,
+        odim0: dim_t,
+        odim1: dim_t,
+        method: c_uint,
+    ) -> c_int;
+
+    fn af_transform(
+        out: *mut af_array,
+        input: af_array,
+        trans: af_array,
+        odim0: dim_t,
+        odim1: dim_t,
+        method: c_uint,
+        is_inverse: bool,
+    ) -> c_int;
+
+    fn af_rotate(
+        out: *mut af_array,
+        input: af_array,
+        theta: c_float,
+        crop: bool,
+        method: c_uint,
+    ) -> c_int;
+
+    fn af_translate(
+        out: *mut af_array,
+        input: af_array,
+        trans0: c_float,
+        trans1: c_float,
+        odim0: dim_t,
+        odim1: dim_t,
+        method: c_uint,
+    ) -> c_int;
+
+    fn af_scale(
+        out: *mut af_array,
+        input: af_array,
+        scale0: c_float,
+        scale1: c_float,
+        odim0: dim_t,
+        odim1: dim_t,
+        method: c_uint,
+    ) -> c_int;
+
+    fn af_skew(
+        out: *mut af_array,
+        input: af_array,
+        skew0: c_float,
+        skew1: c_float,
+        odim0: dim_t,
+        odim1: dim_t,
+        method: c_uint,
+        is_inverse: bool,
+    ) -> c_int;
+
+    fn af_histogram(
+        out: *mut af_array,
+        input: af_array,
+        nbins: c_uint,
+        minval: c_double,
+        maxval: c_double,
+    ) -> c_int;
+
+    fn af_dilate(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
+    fn af_dilate3(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
+    fn af_erode(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
+    fn af_erode3(out: *mut af_array, input: af_array, mask: af_array) -> c_int;
+    fn af_regions(out: *mut af_array, input: af_array, conn: c_uint, aftype: c_uint) -> c_int;
+    fn af_sobel_operator(dx: *mut af_array, dy: *mut af_array, i: af_array, ksize: c_uint)
+        -> c_int;
+    fn af_rgb2gray(
+        out: *mut af_array,
+        input: af_array,
+        r: c_float,
+        g: c_float,
+        b: c_float,
+    ) -> c_int;
+    fn af_gray2rgb(
+        out: *mut af_array,
+        input: af_array,
+        r: c_float,
+        g: c_float,
+        b: c_float,
+    ) -> c_int;
+    fn af_hist_equal(out: *mut af_array, input: af_array, hist: af_array) -> c_int;
+    fn af_hsv2rgb(out: *mut af_array, input: af_array) -> c_int;
+    fn af_rgb2hsv(out: *mut af_array, input: af_array) -> c_int;
+
+    fn af_bilateral(
+        out: *mut af_array,
+        input: af_array,
+        sp_sig: c_float,
+        ch_sig: c_float,
+        iscolor: bool,
+    ) -> c_int;
+
+    fn af_mean_shift(
+        out: *mut af_array,
+        input: af_array,
+        sp_sig: c_float,
+        ch_sig: c_float,
+        iter: c_uint,
+        iscolor: bool,
+    ) -> c_int;
+
+    fn af_medfilt(
+        out: *mut af_array,
+        input: af_array,
+        wlen: dim_t,
+        wwid: dim_t,
+        etype: c_uint,
+    ) -> c_int;
+
+    fn af_medfilt1(out: *mut af_array, input: af_array, wlen: dim_t, etype: c_uint) -> c_int;
+
+    fn af_minfilt(
+        out: *mut af_array,
+        input: af_array,
+        wlen: dim_t,
+        wwid: dim_t,
+        etype: c_uint,
+    ) -> c_int;
+
+    fn af_maxfilt(
+        out: *mut af_array,
+        input: af_array,
+        wlen: dim_t,
+        wwid: dim_t,
+        etype: c_uint,
+    ) -> c_int;
+
+    fn af_gaussian_kernel(
+        out: *mut af_array,
+        rows: c_int,
+        cols: c_int,
+        sigma_r: c_double,
+        sigma_c: c_double,
+    ) -> c_int;
+
+    fn af_color_space(
+        out: *mut af_array,
+        input: af_array,
+        tospace: c_uint,
+        fromspace: c_uint,
+    ) -> c_int;
+
+    fn af_unwrap(
+        out: *mut af_array,
+        input: af_array,
+        wx: dim_t,
+        wy: dim_t,
+        sx: dim_t,
+        sy: dim_t,
+        px: dim_t,
+        py: dim_t,
+        is_column: bool,
+    ) -> c_int;
+
+    fn af_wrap(
+        out: *mut af_array,
+        input: af_array,
+        ox: dim_t,
+        oy: dim_t,
+        wx: dim_t,
+        wy: dim_t,
+        sx: dim_t,
+        sy: dim_t,
+        px: dim_t,
+        py: dim_t,
+        is_column: bool,
+    ) -> c_int;
+
+    fn af_sat(out: *mut af_array, input: af_array) -> c_int;
+
+    fn af_ycbcr2rgb(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int;
+    fn af_rgb2ycbcr(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int;
+    fn af_is_image_io_available(out: *mut bool) -> c_int;
+    fn af_transform_coordinates(
+        out: *mut af_array,
+        tf: af_array,
+        d0: c_float,
+        d1: c_float,
+    ) -> c_int;
+
+    fn af_moments(out: *mut af_array, input: af_array, moment: c_uint) -> c_int;
+    fn af_moments_all(out: *mut c_double, input: af_array, moment: c_uint) -> c_int;
+
+    fn af_canny(
+        out: *mut af_array,
+        input: af_array,
+        thres_type: c_int,
+        low: c_float,
+        high: c_float,
+        swindow: c_uint,
+        is_fast: bool,
+    ) -> c_int;
+    fn af_anisotropic_diffusion(
+        out: *mut af_array,
+        input: af_array,
+        dt: c_float,
+        K: c_float,
+        iters: c_uint,
+        fftype: c_uint,
+        diff_kind: c_uint,
+    ) -> c_int;
+    fn af_confidence_cc(
+        out: *mut af_array,
+        input: af_array,
+        seedx: af_array,
+        seedy: af_array,
+        radius: c_uint,
+        multiplier: c_uint,
+        iterations: c_int,
+        seg_val: c_double,
+    ) -> c_int;
+    fn af_iterative_deconv(
+        out: *mut af_array,
+        input: af_array,
+        ker: af_array,
+        iterations: c_uint,
+        rfactor: c_float,
+        algo: c_uint,
+    ) -> c_int;
+    fn af_inverse_deconv(
+        out: *mut af_array,
+        input: af_array,
+        ker: af_array,
+        gamma: c_float,
+        algo: c_uint,
+    ) -> c_int;
+}
+
+/// Calculate the gradients
+///
+/// The gradients along the first and second dimensions are calculated simultaneously.
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+///
+/// # Return Values
+///
+/// A tuple of Arrays.
+///
+/// The first Array is `dx` which is the gradient along the 1st dimension.
+///
+/// The second Array is `dy` which is the gradient along the 2nd dimension.
+pub fn gradient<T>(input: &Array<T>) -> (Array<T>, Array<T>)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut dx: af_array = std::ptr::null_mut();
+        let mut dy: af_array = std::ptr::null_mut();
+        let err_val = af_gradient(
+            &mut dx as *mut af_array,
+            &mut dy as *mut af_array,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (dx.into(), dy.into())
+    }
+}
+
+/// Load Image into Array
+///
+/// Only, Images with 8/16/32 bits per channel can be loaded using this function.
+///
+/// # Parameters
+///
+/// - `filename` is aboslute path of the image to be loaded.
+/// - `is_color` indicates if the image file at given path is color or gray scale.
+///
+/// # Return Arrays
+///
+/// An Array with pixel values loaded from the image
+#[allow(clippy::match_wild_err_arm)]
+pub fn load_image<T>(filename: String, is_color: bool) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    let cstr_param = match CString::new(filename) {
+        Ok(cstr) => cstr,
+        Err(_) => panic!("CString creation from input filename failed"),
+    };
+    let trgt_type = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err1 = af_load_image(&mut temp as *mut af_array, cstr_param.as_ptr(), is_color);
+        HANDLE_ERROR(AfError::from(err1));
+
+        let mut img: af_array = std::ptr::null_mut();
+        let err2 = af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint);
+        HANDLE_ERROR(AfError::from(err2));
+
+        img.into()
+    }
+}
+
+/// Load Image into Array in it's native type
+///
+/// This load image function allows you to load images as U8, U16 or F32
+/// depending on the type of input image as shown by the table below.
+///
+///  Bits per Color (Gray/RGB/RGBA Bits Per Pixel) | Array Type  | Range
+/// -----------------------------------------------|-------------|---------------
+///   8 ( 8/24/32  BPP)                            | u8          | 0 - 255
+///  16 (16/48/64  BPP)                            | u16         | 0 - 65535
+///  32 (32/96/128 BPP)                            | f32         | 0 - 1
+///
+/// # Parameters
+///
+/// - `filename` is name of file to be loaded
+///
+/// # Return Arrays
+///
+/// An Array with pixel values loaded from the image
+#[allow(clippy::match_wild_err_arm)]
+pub fn load_image_native<T>(filename: String) -> Array<T>
+where
+    T: HasAfEnum + ImageNativeType,
+{
+    let cstr_param = match CString::new(filename) {
+        Ok(cstr) => cstr,
+        Err(_) => panic!("CString creation from input filename failed"),
+    };
+    let trgt_type = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err1 = af_load_image_native(&mut temp as *mut af_array, cstr_param.as_ptr());
+        HANDLE_ERROR(AfError::from(err1));
+
+        let mut img: af_array = std::ptr::null_mut();
+        let err2 = af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint);
+        HANDLE_ERROR(AfError::from(err2));
+
+        img.into()
+    }
+}
+
+/// Save an Array to an image file
+///
+/// # Parameters
+///
+/// - `filename` is the abolute path(includes filename) at which input Array is going to be saved
+/// - `input` is the Array to be stored into the image file
+#[allow(clippy::match_wild_err_arm)]
+pub fn save_image<T>(filename: String, input: &Array<T>)
+where
+    T: HasAfEnum + RealNumber,
+{
+    let cstr_param = match CString::new(filename) {
+        Ok(cstr) => cstr,
+        Err(_) => panic!("CString creation from input filename failed"),
+    };
+    unsafe {
+        let err_val = af_save_image(cstr_param.as_ptr(), input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Save an Array without modifications to an image file
+///
+/// This function only accepts U8, U16, F32 arrays. These arrays are saved to images without any modifications. You must also note that note all image type support 16 or 32 bit images. The best options for 16 bit images are PNG, PPM and TIFF. The best option for 32 bit images is TIFF. These allow lossless storage.
+///
+/// The images stored have the following properties:
+///
+///  Array Type  | Bits per Color (Gray/RGB/RGBA Bits Per Pixel) | Range
+/// -------------|-----------------------------------------------|---------------
+///  U8          |  8 ( 8/24/32  BPP)                            | 0 - 255
+///  U16         | 16 (16/48/64  BPP)                            | 0 - 65535
+///  F32         | 32 (32/96/128 BPP)                            | 0 - 1
+///
+/// # Parameters
+///
+/// - `filename` is name of file to be saved
+/// - `input` is the Array to be saved. Should be U8 for saving 8-bit image, U16 for 16-bit image, and F32 for 32-bit image.
+#[allow(clippy::match_wild_err_arm)]
+pub fn save_image_native<T>(filename: String, input: &Array<T>)
+where
+    T: HasAfEnum + ImageNativeType,
+{
+    let cstr_param = match CString::new(filename) {
+        Ok(cstr) => cstr,
+        Err(_) => panic!("CString creation from input filename failed"),
+    };
+    unsafe {
+        let err_val = af_save_image_native(cstr_param.as_ptr(), input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Resize an Image
+///
+/// Resizing an input image can be done using either NEAREST or BILINEAR interpolations.
+/// Nearest interpolation will pick the nearest value to the location, whereas bilinear
+/// interpolation will do a weighted interpolation for calculate the new size.
+///
+/// This function does not differentiate between images and data. As long as the array is defined
+/// and the output dimensions are not 0, it will resize any type or size of array.
+///
+/// # Parameters
+///
+/// - `input` is the image to be resized
+/// - `odim0` is the output height
+/// - `odim1` is the output width
+/// - `method` indicates which interpolation method to use for resizing. It uses enum
+/// [InterpType](./enum.InterpType.html) to identify the interpolation method.
+///
+/// # Return Values
+///
+/// Resized Array
+pub fn resize<T: HasAfEnum>(
+    input: &Array<T>,
+    odim0: i64,
+    odim1: i64,
+    method: InterpType,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_resize(
+            &mut temp as *mut af_array,
+            input.get(),
+            odim0 as dim_t,
+            odim1 as dim_t,
+            method as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Transform(Affine) an Image
+///
+/// The transform function uses an affine transform matrix to tranform an input image into a new
+/// one. The transform matrix tf is a 3x2 matrix of type float. The matrix operation is applied to each
+/// location (x, y) that is then transformed to (x', y') of the new array. Hence the transformation
+/// is an element-wise operation.
+///
+/// The operation is as below: tf = [r00 r10 r01 r11 t0 t1]
+///
+/// x' = x * r00 + y * r01 + t0; y' = x * r10 + y * r11 + t1;
+///
+/// Interpolation types of NEAREST, LINEAR, BILINEAR and CUBIC are allowed. Affine transforms can be used for various purposes. [translate](./fn.translate.html), [scale](./fn.scale.html) and [skew](./fn.skew.html) are
+/// specializations of the transform function.
+///
+/// This function can also handle batch operations.
+///
+/// # Parameters
+///
+/// - `input` is the image to be resized
+/// - `trans` is the transformation matrix to be used for image transformation
+/// - `odim0` is the output height
+/// - `odim1` is the output width
+/// - `method` indicates which interpolation method to use for resizing. It uses enum
+/// [InterpType](./enum.InterpType.html) to identify the interpolation method.
+/// - `is_inverse` indicates if to apply inverse/forward transform
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn transform<T: HasAfEnum>(
+    input: &Array<T>,
+    trans: &Array<f32>,
+    odim0: i64,
+    odim1: i64,
+    method: InterpType,
+    is_inverse: bool,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_transform(
+            &mut temp as *mut af_array,
+            input.get(),
+            trans.get(),
+            odim0 as dim_t,
+            odim1 as dim_t,
+            method as c_uint,
+            is_inverse,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Rotate an Image
+///
+/// Rotating an input image can be done using either NEAREST or BILINEAR interpolations.
+/// Nearest interpolation will pick the nearest value to the location, whereas bilinear
+/// interpolation will do a weighted interpolation for calculate the new size.
+///
+/// This function does not differentiate between images and data. As long as the array is defined,
+/// it will rotate any type or size of array.
+///
+/// The crop option allows you to choose whether to resize the image. If crop is set to false, ie.
+/// the entire rotated image will be a part of the array and the new array size will be greater
+/// than or equal to the input array size. If crop is set to true, then the new array size is same
+/// as the input array size and the data that falls outside the boundaries of the array is
+/// discarded.
+///
+/// Any location of the rotated array that does not map to a location of the input array is set to
+/// 0.
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `theta` is the amount of angle (in radians) image should be rotated
+/// - `crop` indicates if the rotated image has to be cropped to original size
+/// - `method` indicates which interpolation method to use for rotating the image. It uses enum
+/// [InterpType](./enum.InterpType.html) to identify the interpolation method.
+///
+/// # Return Values
+///
+/// Rotated Array
+pub fn rotate<T: HasAfEnum>(
+    input: &Array<T>,
+    theta: f64,
+    crop: bool,
+    method: InterpType,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_rotate(
+            &mut temp as *mut af_array,
+            input.get(),
+            theta as c_float,
+            crop,
+            method as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Translate an Image
+///
+/// Translating an image is moving it along 1st and 2nd dimensions by trans0 and trans1. Positive
+/// values of these will move the data towards negative x and negative y whereas negative values of
+/// these will move the positive right and positive down. See the example below for more.
+///
+/// To specify an output dimension, use the odim0 and odim1 for dim0 and dim1 respectively. The
+/// size of 2rd and 3rd dimension is same as input. If odim0 and odim1 and not defined, then the
+/// output dimensions are same as the input dimensions and the data out of bounds will be
+/// discarded.
+///
+/// All new values that do not map to a location of the input array are set to 0.
+///
+/// Translate is a special case of the [transform](./fn.transform.html) function.
+///
+/// # Parameters
+///
+/// - `input` is input image
+/// - `trans0` is amount by which the first dimension is translated
+/// - `trans1` is amount by which the second dimension is translated
+/// - `odim0` is the first output dimension
+/// - `odim1` is the second output dimension
+/// - `method` is the interpolation type (Nearest by default)
+///
+/// # Return Values
+///
+/// Translated Image(Array).
+pub fn translate<T: HasAfEnum>(
+    input: &Array<T>,
+    trans0: f32,
+    trans1: f32,
+    odim0: i64,
+    odim1: i64,
+    method: InterpType,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_translate(
+            &mut temp as *mut af_array,
+            input.get(),
+            trans0,
+            trans1,
+            odim0 as dim_t,
+            odim1 as dim_t,
+            method as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Scale an Image
+///
+/// Scale is the same functionality as [resize](./fn.resize.html) except that the scale function uses the transform kernels. The other difference is that scale does not set boundary values to be the boundary of the input array. Instead these are set to 0.
+///
+/// Scale is a special case of the [transform](./fn.transform.html) function.
+///
+/// # Parameters
+///
+/// - `input` is input image
+/// - `trans0` is amount by which the first dimension is translated
+/// - `trans1` is amount by which the second dimension is translated
+/// - `odim0` is the first output dimension
+/// - `odim1` is the second output dimension
+/// - `method` is the interpolation type (Nearest by default)
+///
+/// # Return Values
+///
+/// Translated Image(Array).
+pub fn scale<T: HasAfEnum>(
+    input: &Array<T>,
+    scale0: f32,
+    scale1: f32,
+    odim0: i64,
+    odim1: i64,
+    method: InterpType,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_scale(
+            &mut temp as *mut af_array,
+            input.get(),
+            scale0,
+            scale1,
+            odim0 as dim_t,
+            odim1 as dim_t,
+            method as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Skew an image
+///
+/// Skew function skews the input array along dim0 by skew0 and along dim1 by skew1. The skew
+/// areguments are in radians. Skewing the data means the data remains parallel along 1 dimensions
+/// but the other dimensions gets moved along based on the angle. If both skew0 and skew1 are
+/// specified, then the data will be skewed along both directions. Explicit output dimensions
+/// can be specified using odim0 and odim1. All new values that do not map to a location of the input array are set to 0.
+///
+/// Skew is a special case of the [transform](./fn.transform.html) function.
+///
+/// # Parameters
+///
+/// - `input` is the image to be skewed
+/// - `skew0` is the factor by which data is skewed along first dimension
+/// - `skew1` is the factor by which data is skewed along second dimension
+/// - `odim0` is the output length along first dimension
+/// - `odim1` is the output length along second dimension
+/// - `method` indicates which interpolation method to use for rotating the image. It uses enum
+/// [InterpType](./enum.InterpType.html) to identify the interpolation method.
+/// - `is_inverse` indicates if to apply inverse/forward transform
+///
+/// # Return Values
+///
+/// Skewed Image
+pub fn skew<T: HasAfEnum>(
+    input: &Array<T>,
+    skew0: f32,
+    skew1: f32,
+    odim0: i64,
+    odim1: i64,
+    method: InterpType,
+    is_inverse: bool,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_skew(
+            &mut temp as *mut af_array,
+            input.get(),
+            skew0,
+            skew1,
+            odim0 as dim_t,
+            odim1 as dim_t,
+            method as c_uint,
+            is_inverse,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Compute Histogram of an Array
+///
+/// A histogram is a representation of the distribution of given data. This representation is
+/// essentially a graph consisting of the data range or domain on one axis and frequency of
+/// occurence on the other axis. All the data in the domain is counted in the appropriate bin. The
+/// total number of elements belonging to each bin is known as the bin's frequency.
+///
+/// The regular histogram function creates bins of equal size between the minimum and maximum of
+/// the input data (min and max are calculated internally). The histogram min-max function takes
+/// input parameters minimum and maximum, and divides the bins into equal sizes within the range
+/// specified by min and max parameters. All values less than min in the data range are placed in
+/// the first (min) bin and all values greater than max will be placed in the last (max) bin.
+///
+/// # Parameters
+///
+/// - `input` is the Array whose histogram has to be computed
+/// - `nbins` is the number bins the input data has to be categorized into.
+/// - `minval` is the minimum value of bin ordering
+/// - `maxval` is the maximum value of bin ordering
+///
+/// # Return Values
+///
+/// Histogram of input Array
+pub fn histogram<T>(input: &Array<T>, nbins: u32, minval: f64, maxval: f64) -> Array<u32>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_histogram(
+            &mut temp as *mut af_array,
+            input.get(),
+            nbins,
+            minval,
+            maxval,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Dilate an Image
+///
+/// The dilation function takes two pieces of data as inputs. The first is the input image to be
+/// morphed, and the second is the mask indicating the neighborhood around each pixel to match.
+///
+/// In dilation, for each pixel, the mask is centered at the pixel. If the center pixel of the mask
+/// matches the corresponding pixel on the image, then the mask is accepted. If the center pixels
+/// do not matches, then the mask is ignored and no changes are made.
+///
+/// For further reference, see [here](https://en.wikipedia.org/wiki/Dilation_(morphology)).
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `mask` is the morphological operation mask
+///
+/// # Return Values
+///
+/// Dilated Image(Array)
+pub fn dilate<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_dilate(&mut temp as *mut af_array, input.get(), mask.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Erode an Image
+///
+/// The erosion function is a morphological transformation on an image that requires two inputs.
+/// The first is the image to be morphed, and the second is the mask indicating neighborhood that
+/// must be white in order to preserve each pixel.
+///
+/// In erode, for each pixel, the mask is centered at the pixel. If each pixel of the mask matches
+/// the corresponding pixel on the image, then no change is made. If there is at least one
+/// mismatch, then pixels are changed to the background color (black).
+///
+/// For further reference, see [here](https://en.wikipedia.org/wiki/Erosion_(morphology)).
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `mask` is the morphological operation mask
+///
+/// # Return Values
+///
+/// Eroded Image(Array)
+pub fn erode<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_erode(&mut temp as *mut af_array, input.get(), mask.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Dilate a Volume
+///
+/// Dilation for a volume is similar to the way dilation works on an image. Only difference is that
+/// the masking operation is performed on a volume instead of a rectangular region.
+///
+/// # Parameters
+///
+/// - `input` is the input volume
+/// - `mask` is the morphological operation mask
+///
+/// # Return Values
+///
+/// Dilated Volume(Array)
+pub fn dilate3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_dilate3(&mut temp as *mut af_array, input.get(), mask.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Erode a Volume
+///
+/// Erosion for a volume is similar to the way erosion works on an image. Only difference is that
+/// the masking operation is performed on a volume instead of a rectangular region.
+///
+/// # Parameters
+///
+/// - `input` is the input volume
+/// - `mask` is the morphological operation mask
+///
+/// # Return Values
+///
+/// Eroded Volume(Array)
+pub fn erode3<T>(input: &Array<T>, mask: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_erode3(&mut temp as *mut af_array, input.get(), mask.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Bilateral Filter.
+///
+/// A bilateral filter is a edge-preserving filter that reduces noise in an image. The intensity of
+/// each pixel is replaced by a weighted average of the intensities of nearby pixels. The weights
+/// follow a Gaussian distribution and depend on the distance as well as the color distance.
+///
+/// The bilateral filter requires the size of the filter (in pixels) and the upper bound on color
+/// values, N, where pixel values range from 0–N inclusively.
+///
+/// # Parameters
+///
+/// - `input` array is the input image
+/// - `spatial_sigma` is the spatial variance parameter that decides the filter window
+/// - `chromatic_sigma` is the chromatic variance parameter
+/// - `iscolor` indicates if the input is color image or grayscale
+///
+/// # Return Values
+///
+/// Filtered Image - Array
+pub fn bilateral<T>(
+    input: &Array<T>,
+    spatial_sigma: f32,
+    chromatic_sigma: f32,
+    iscolor: bool,
+) -> Array<T::AbsOutType>
+where
+    T: HasAfEnum + ImageFilterType,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_bilateral(
+            &mut temp as *mut af_array,
+            input.get(),
+            spatial_sigma,
+            chromatic_sigma,
+            iscolor,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Meanshift Filter.
+///
+/// A meanshift filter is an edge-preserving smoothing filter commonly used in object tracking and
+/// image segmentation.
+///
+/// This filter replaces each pixel in the image with the mean of the values within a given given
+/// color and spatial radius. The meanshift filter is an iterative algorithm that continues until a
+/// maxium number of iterations is met or until the value of the means no longer changes.
+///
+/// # Parameters
+///
+/// - `input` array is the input image
+/// - `spatial_sigma` is the spatial variance parameter that decides the filter window
+/// - `chromatic_sigma` is the chromatic variance parameter
+/// - `iter` is the number of iterations filter operation is performed
+/// - `iscolor` indicates if the input is color image or grayscale
+///
+/// # Return Values
+///
+/// Filtered Image - Array
+pub fn mean_shift<T>(
+    input: &Array<T>,
+    spatial_sigma: f32,
+    chromatic_sigma: f32,
+    iter: u32,
+    iscolor: bool,
+) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_mean_shift(
+            &mut temp as *mut af_array,
+            input.get(),
+            spatial_sigma,
+            chromatic_sigma,
+            iter,
+            iscolor,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! filt_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `input` is the input image(Array)
+        /// - `wlen` is the horizontal length of the filter
+        /// - `hlen` is the vertical length of the filter
+        /// - `etype` is enum of type [BorderType](./enum.BorderType.html)
+        ///
+        ///# Return Values
+        ///
+        /// An Array with filtered image data.
+        pub fn $fn_name<T>(input: &Array<T>, wlen: u64, wwid: u64, etype: BorderType) -> Array<T>
+        where
+            T: HasAfEnum + ImageFilterType,
+        {
+            unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array,
+                    input.get(),
+                    wlen as dim_t,
+                    wwid as dim_t,
+                    etype as c_uint,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+filt_func_def!("Median filter", medfilt, af_medfilt);
+filt_func_def!(
+    "Box filter with minimum as box operation",
+    minfilt,
+    af_minfilt
+);
+filt_func_def!(
+    "Box filter with maximum as box operation",
+    maxfilt,
+    af_maxfilt
+);
+
+/// Creates a Gaussian Kernel.
+///
+/// This function creates a kernel of a specified size that contains a Gaussian distribution. This
+/// distribution is normalized to one. This is most commonly used when performing a Gaussian blur
+/// on an image. The function takes two sets of arguments, the size of the kernel (width and height
+/// in pixels) and the sigma parameters (for row and column) which effect the distribution of the
+/// weights in the y and x directions, respectively.
+///
+/// Changing sigma causes the weights in each direction to vary. Sigma is calculated internally as
+/// (0.25 * rows + 0.75) for rows and similarly for columns.
+///
+/// # Parameters
+///
+/// - `rows` is number of rows of kernel
+/// - `cols` is number of cols of kernel
+/// - `sigma_r` is standard deviation of rows
+/// - `sigma_c` is standard deviation of cols
+///
+/// # Return Values
+///
+/// An Array with gaussian kernel values
+pub fn gaussian_kernel(rows: i32, cols: i32, sigma_r: f64, sigma_c: f64) -> Array<f32> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_gaussian_kernel(&mut temp as *mut af_array, rows, cols, sigma_r, sigma_c);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Color space conversion
+///
+/// Following are the supported conversions
+///
+/// - RGB => GRAY
+/// - GRAY => RGB
+/// - RGB => HSV
+/// - HSV => RGB
+/// - YCbCr => RGB
+/// - RGB => YCbCr
+///
+/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores
+/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of
+/// these three values produces the gamut of unique colors.
+///
+/// HSV (Hue, Saturation, Value), also known as HSB (hue, saturation, brightness), is often used by
+/// artists because it is more natural to think about a color in terms of hue and saturation than
+/// in terms of additive or subtractive color components (as in RGB). HSV is a transformation of
+/// RGB colorspace; its components and colorimetry are relative to the RGB colorspace from which it
+/// was derived. Like RGB, HSV also uses 3 values per pixel.
+///
+/// GRAY is a single channel color space where pixel value ranges from 0 to 1. Zero represents
+/// black, one represent white and any value between zero & one is a gray value
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `tospace` is the target color space. Takes values of [ColorSpace](./enum.ColorSpace.html)
+/// - `fromspace` is the source image color space. Takes values of
+/// [ColorSpace](./enum.ColorSpace.html)
+///
+/// # Return Values
+///
+/// An Array with input image values in target color space
+pub fn color_space<T>(input: &Array<T>, tospace: ColorSpace, fromspace: ColorSpace) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_color_space(
+            &mut temp as *mut af_array,
+            input.get(),
+            tospace as c_uint,
+            fromspace as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find blobs in given image.
+///
+/// Given a binary image (with zero representing background pixels), regions computes a floating
+/// point image where each connected component is labeled from 1 to N, the total number of
+/// components in the image.
+///
+/// A component is defined as one or more nonzero pixels that are connected by the specified
+/// connectivity (either [`Connectivity::FOUR`](./enum.Connectivity.html) or [`Connectivity::EIGHT`](./enum.Connectivity.html)) in two dimensions.
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `conn` can take one of the values of [Connectivity](./enum.Connectivity.html)
+///
+/// # Return Values
+///
+/// Array with labels indicating different regions
+pub fn regions<OutType>(input: &Array<bool>, conn: Connectivity) -> Array<OutType>
+where
+    OutType: HasAfEnum + RealNumber,
+{
+    let otype = OutType::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_regions(
+            &mut temp as *mut af_array,
+            input.get(),
+            conn as c_uint,
+            otype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Sobel Operator
+///
+/// Sobel operators perform a 2-D spatial gradient measurement on an image to emphasize the regions
+/// of high spatial frequency, namely edges. A more in depth discussion on it can be found [here](https://en.wikipedia.org/wiki/Sobel_operator).
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `ker_size` is the kernel size of sobel operator
+///
+/// # Return Values
+///
+/// A tuple of Arrays.
+///
+/// The first Array has derivatives along horizontal direction
+///
+/// The second Array has derivatives along vertical direction
+pub fn sobel<T>(input: &Array<T>, ker_size: u32) -> (Array<T::SobelOutType>, Array<T::SobelOutType>)
+where
+    T: HasAfEnum + ImageFilterType,
+    T::SobelOutType: HasAfEnum,
+{
+    unsafe {
+        let mut dx: af_array = std::ptr::null_mut();
+        let mut dy: af_array = std::ptr::null_mut();
+        let err_val = af_sobel_operator(
+            &mut dx as *mut af_array,
+            &mut dy as *mut af_array,
+            input.get(),
+            ker_size,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (dx.into(), dy.into())
+    }
+}
+
+/// Histogram Equalization
+///
+/// # Parameters
+///
+/// - `input` is the input Array to be equalized
+/// - `hist` is the Array to be used for equalizing input
+///
+/// # Return Values
+/// Equalized Array
+pub fn hist_equal<T>(input: &Array<T>, hist: &Array<u32>) -> Array<T>
+where
+    T: HasAfEnum + RealNumber,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_hist_equal(&mut temp as *mut af_array, input.get(), hist.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! grayrgb_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `r` is fraction of red channel to appear in output
+        /// - `g` is fraction of green channel to appear in output
+        /// - `b` is fraction of blue channel to appear in output
+        ///
+        ///#Return Values
+        ///
+        ///An Array with image data in target color space
+        pub fn $fn_name<T>(input: &Array<T>, r: f32, g: f32, b: f32) -> Array<T>
+        where
+            T: HasAfEnum + GrayRGBConvertible,
+        {
+            unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(&mut temp as *mut af_array, input.get(), r, g, b);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+grayrgb_func_def!("Color(RGB) to Grayscale conversion", rgb2gray, af_rgb2gray);
+grayrgb_func_def!("Grayscale to Color(RGB) conversion", gray2rgb, af_gray2rgb);
+
+macro_rules! hsvrgb_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => {
+        #[doc=$doc_str]
+        pub fn $fn_name<T>(input: &Array<T>) -> Array<T>
+        where
+            T: HasAfEnum + RealFloating,
+        {
+            unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(&mut temp as *mut af_array, input.get());
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+hsvrgb_func_def!("HSV to RGB color space conversion", hsv2rgb, af_hsv2rgb);
+hsvrgb_func_def!("RGB to HSV color space conversion", rgb2hsv, af_rgb2hsv);
+
+/// Generate an array with image windows as columns
+///
+/// unwrap takes in an input image along with the window sizes wx and wy, strides sx and sy, and
+/// padding px and py. This function then generates a matrix where each windows is an independent
+/// column.
+///
+/// The number of columns (rows if is_column is true) in the output array are govenered by the
+/// number of windows that can be fit along x and y directions. Padding is applied along all 4
+/// sides of the matrix with px defining the height of the padding along dim 0 and py defining the
+/// width of the padding along dim 1.
+///
+/// The first column window is always at the top left corner of the input including padding. If a
+/// window cannot fit before the end of the matrix + padding, it is skipped from the generated
+/// matrix.
+///
+/// Padding can take a maximum value of window - 1 repectively for x and y.
+///
+/// For multiple channels (3rd and 4th dimension), the generated matrix contains the same number of
+/// channels as the input matrix. Each channel of the output matrix corresponds to the same channel
+/// of the input.
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `wx` is the block window size along 0th-dimension between \[1, input.dims\[0\] + px\]
+/// - `wy` is the block window size along 1st-dimension between \[1, input.dims\[1\] + py\]
+/// - `sx` is the stride along 0th-dimension
+/// - `sy` is the stride along 1st-dimension
+/// - `px` is the padding along 0th-dimension between [0, wx). Padding is applied both before and after.
+/// - `py` is the padding along 1st-dimension between [0, wy). Padding is applied both before and after.
+/// - `is_column` specifies the layout for the unwrapped patch. If is_column is false, the unrapped patch is laid out as a row.
+///
+/// # Return Values
+///
+/// An Array with image windows as columns
+///
+/// # Examples
+///
+/// ```text
+/// A [5 5 1 1]
+/// 10 15 20 25 30
+/// 11 16 21 26 31
+/// 12 17 22 27 32
+/// 13 18 23 28 33
+/// 14 19 24 29 34
+///
+/// // Window 3x3, strides 1x1, padding 0x0
+/// unwrap(A, 3, 3, 1, 1, 0, 0, False) [9 9 1 1]
+/// 10 11 12 15 16 17 20 21 22
+/// 11 12 13 16 17 18 21 22 23
+/// 12 13 14 17 18 19 22 23 24
+/// 15 16 17 20 21 22 25 26 27
+/// 16 17 18 21 22 23 26 27 28
+/// 17 18 19 22 23 24 27 28 29
+/// 20 21 22 25 26 27 30 31 32
+/// 21 22 23 26 27 28 31 32 33
+/// 22 23 24 27 28 29 32 33 34
+///
+/// // Window 3x3, strides 1x1, padding 1x1
+/// unwrap(A, 3, 3, 1, 1, 1, 1, False) [9 25 1 1]
+///  0  0  0  0  0  0 10 11 12 13  0 15 16 17 18  0 20 21 22 23  0 25 26 27 28
+///  0  0  0  0  0 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
+///  0  0  0  0  0 11 12 13 14  0 16 17 18 19  0 21 22 23 24  0 26 27 28 29  0
+///  0 10 11 12 13  0 15 16 17 18  0 20 21 22 23  0 25 26 27 28  0 30 31 32 33
+/// 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
+/// 11 12 13 14  0 16 17 18 19  0 21 22 23 24  0 26 27 28 29  0 31 32 33 34  0
+///  0 15 16 17 18  0 20 21 22 23  0 25 26 27 28  0 30 31 32 33  0  0  0  0  0
+/// 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34  0  0  0  0  0
+/// 16 17 18 19  0 21 22 23 24  0 26 27 28 29  0 31 32 33 34  0  0  0  0  0  0
+/// ```
+#[allow(clippy::too_many_arguments)]
+pub fn unwrap<T: HasAfEnum>(
+    input: &Array<T>,
+    wx: i64,
+    wy: i64,
+    sx: i64,
+    sy: i64,
+    px: i64,
+    py: i64,
+    is_column: bool,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_unwrap(
+            &mut temp as *mut af_array,
+            input.get(),
+            wx,
+            wy,
+            sx,
+            sy,
+            px,
+            py,
+            is_column,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Converts unwrapped image to an image
+///
+/// Wrap takes an unwrapped image (see unwrap()) and converts it back to an image.
+///
+/// The inputs to this function should be the same as the inputs used to generate the unwrapped
+/// image.
+///
+/// # Parameters
+///
+/// - `input` is the output of unwrap function call
+/// - `ox` is the 0th-dimension of output image
+/// - `oy` is the 1st-dimension of output image
+/// - `wx` is the block window size along 0th-dimension between
+/// - `wy` is the block window size along 1st-dimension between
+/// - `sx` is the stride along 0th-dimension
+/// - `sy` is the stride along 1st-dimension
+/// - `px` is the padding used along 0th-dimension between [0, wx).
+/// - `py` is the padding used along 1st-dimension between [0, wy).
+/// - `is_column` specifies the layout for the unwrapped patch. If is_column is false, the rows are treated as the patches
+///
+/// # Return Values
+///
+/// Image(Array) created from unwrapped Image(Array)
+#[allow(clippy::too_many_arguments)]
+pub fn wrap<T: HasAfEnum>(
+    input: &Array<T>,
+    ox: i64,
+    oy: i64,
+    wx: i64,
+    wy: i64,
+    sx: i64,
+    sy: i64,
+    px: i64,
+    py: i64,
+    is_column: bool,
+) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_wrap(
+            &mut temp as *mut af_array,
+            input.get(),
+            ox,
+            oy,
+            wx,
+            wy,
+            sx,
+            sy,
+            px,
+            py,
+            is_column,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Summed area table of an Image
+///
+/// # Parameters
+///
+/// - `input` is the input image
+///
+/// # Return Values
+///
+/// Summed area table (a.k.a Integral Image) of the input image.
+pub fn sat<T>(input: &Array<T>) -> Array<T::AggregateOutType>
+where
+    T: HasAfEnum + RealNumber,
+    T::AggregateOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_sat(&mut temp as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// RGB to YCbCr colorspace converter.
+///
+/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores
+/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of
+/// these three values produces the gamut of unique colors.
+///
+/// YCbCr is a family of color spaces used as a part of the color image pipeline in video and
+/// digital photography systems where Y is luma component and Cb & Cr are the blue-difference and
+/// red-difference chroma components.
+///
+/// Input array to this function should be of real data in the range [0,1].
+///
+/// # Parameters
+///
+/// - `input` is the input image in RGB color space
+/// - `standard` is the target color space - [YCbCr standard](./enum.YCCStd.html)
+///
+/// # Return Values
+///
+/// Image(Array) in YCbCr color space
+pub fn rgb2ycbcr<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_rgb2ycbcr(&mut temp as *mut af_array, input.get(), standard as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// YCbCr to RGB colorspace converter.
+///
+/// YCbCr is a family of color spaces used as a part of the color image pipeline in video and
+/// digital photography systems where Y is luma component and Cb & Cr are the blue-difference and
+/// red-difference chroma components.
+///
+/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores
+/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of
+/// these three values produces the gamut of unique colors.
+///
+/// Input array to this function should be of real data with the following range in their
+/// respective channels.
+///
+/// - Y  −> [16,219]
+/// - Cb −> [16,240]
+/// - Cr −> [16,240]
+///
+/// # Parameters
+///
+/// - `input` is the input image in YCbCr color space
+/// - `standard` is the [YCbCr standard](./enum.YCCStd.html) in which input image color space is
+/// present.
+///
+/// # Return Values
+///
+/// Image(Array) in RGB color space
+pub fn ycbcr2rgb<T>(input: &Array<T>, standard: YCCStd) -> Array<T>
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_ycbcr2rgb(&mut temp as *mut af_array, input.get(), standard as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Function to check if Image I/O is available
+///
+/// # Parameters
+///
+/// None
+///
+/// # Return Values
+///
+/// Return a boolean indicating if ArrayFire was compiled with Image I/O support
+pub fn is_imageio_available() -> bool {
+    let mut temp: bool = false;
+    unsafe {
+        af_is_image_io_available(&mut temp as *mut bool);
+    }
+    temp
+}
+
+/// Transform input coordinates
+///
+/// The transform function uses a perspective transform matrix to transform input coordinates
+/// (given as two dimensions) into a coordinates matrix.
+///
+/// The output is a 4x2 matrix, indicating the coordinates of the 4 bidimensional transformed
+/// points.
+///
+/// # Parameters
+///
+/// - `tf` is the transformation matrix
+/// - `d0` is the first input dimension
+/// - `d1` is the second input dimension
+///
+/// # Return Values
+///
+/// Transformed coordinates
+pub fn transform_coords<T>(tf: &Array<T>, d0: f32, d1: f32) -> Array<T>
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_transform_coordinates(&mut temp as *mut af_array, tf.get(), d0, d1);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find Image moments
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `moment` is the type of moment to be computed, takes a value of
+/// [enum](./enum.MomentType.html)
+///
+/// # Return Values
+///
+/// Moments Array
+pub fn moments<T>(input: &Array<T>, moment: MomentType) -> Array<f32>
+where
+    T: HasAfEnum + MomentsComputable,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_moments(&mut temp as *mut af_array, input.get(), moment as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find Image moment for whole image
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `moment` is the type of moment to be computed, takes a value of
+/// [enum](./enum.MomentType.html)
+///
+/// # Return Values
+///
+/// Moment value of the whole image
+pub fn moments_all<T>(input: &Array<T>, moment: MomentType) -> f64
+where
+    T: HasAfEnum + MomentsComputable,
+{
+    let mut temp: f64 = 0.0;
+    unsafe {
+        let err_val = af_moments_all(&mut temp as *mut c_double, input.get(), moment as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    temp
+}
+
+/// One dimensional median filter on image
+///
+/// # Parameters
+///
+///  - `input` is the input image(Array)
+///  - `wlen` is the horizontal length of the filter
+///  - `etype` is enum of type [BorderType](./enum.BorderType.html)
+///
+/// # Return Values
+///
+/// An Array with filtered image data.
+pub fn medfilt1<T>(input: &Array<T>, wlen: u64, etype: BorderType) -> Array<T>
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_medfilt1(
+            &mut temp as *mut af_array,
+            input.get(),
+            wlen as dim_t,
+            etype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Canny edge detection operator
+///
+/// The Canny edge detector is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images. A more in depth discussion on it can be found [here](https://en.wikipedia.org/wiki/Canny_edge_detector).
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `threshold_type` helps determine if user set high threshold is to be used or not. It can take values defined by the enum [CannyThresholdType](./enum.CannyThresholdType.html)
+/// - `low` is the lower threshold % of the maximum or auto-derived high
+/// - `high` is the higher threshold % of maximum value in gradient image used in hysteresis procedure. This value is ignored if [CannyThresholdType::OTSU](./enum.CannyThresholdType.html) is chosen.
+/// - `sobel_window` is the window size of sobel kernel for computing gradient direction and magnitude.
+/// - `is_fast` indicates if L<SUB>1</SUB> norm(faster but less accurate) is used to compute image gradient magnitude instead of L<SUB>2</SUB> norm.
+///
+/// # Return Values
+///
+/// An Array of binary type [DType::B8](./enum.DType.html) indicating edges(All pixels with
+/// non-zero values are edges).
+pub fn canny<T>(
+    input: &Array<T>,
+    threshold_type: CannyThresholdType,
+    low: f32,
+    high: f32,
+    sobel_window: u32,
+    is_fast: bool,
+) -> Array<bool>
+where
+    T: HasAfEnum + EdgeComputable,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_canny(
+            &mut temp as *mut af_array,
+            input.get(),
+            threshold_type as c_int,
+            low,
+            high,
+            sobel_window as c_uint,
+            is_fast,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Anisotropic smoothing filter
+///
+/// Anisotropic diffusion algorithm aims at removing noise in the images
+/// while preserving important features such as edges. The algorithm
+/// essentially creates a scale space representation of the original
+/// image, where image from previous step is used to create a new version
+/// of blurred image using the diffusion process. Standard isotropic diffusion
+/// methods such as gaussian blur, doesn't take into account the local
+/// content(smaller neighborhood of current processing pixel) while removing
+/// noise. Anisotropic diffusion uses the flux equations given below to
+/// achieve that. Flux equation is the formula used by the diffusion process
+/// to determine how much a pixel in neighborhood should contribute to
+/// the blurring operation being done at the current pixel at a given iteration.
+///
+/// The flux function can be either exponential or quadratic.
+///
+/// <table>
+/// <caption id="multi row">Available Flux Functions</caption>
+/// <tr>
+///     <td align="center" style="vertical-align:middle;">
+///       AF_FLUX_QUADRATIC
+///     </td>
+///     <td align="center">
+///       \begin{equation}
+///         \frac{1}{1 + (\frac{\| \nabla I\|}{K})^2}
+///       \end{equation}
+///     </td>
+/// </tr>
+/// <tr>
+///     <td align="center" style="vertical-align:middle;">
+///       AF_FLUX_EXPONENTIAL
+///     </td>
+///     <td align="center">
+///       \begin{equation}
+///         \exp{-(\frac{\| \nabla I\|}{K})^2}
+///       \end{equation}
+///     </td>
+/// </tr>
+/// </table>
+///
+/// Please be cautious using the time step parameter to the function.
+/// Appropriate time steps for solving this type of p.d.e. depend on
+/// the dimensionality of the image and the order of the equation.
+/// Stable values for most 2D and 3D functions are 0.125 and 0.0625,
+/// respectively. The time step values are automatically constrained
+/// to the stable value.
+///
+/// Another input parameter to be cautious about is the conductance
+/// parameter, lower values strongly preserve image features and
+/// vice-versa. For human vision, this value ranges from 0.5 to 2.0.
+///
+/// # Parameters
+///
+/// - `img` is the noisy input image
+/// - `dt` is the timestep for diffusion equation
+/// - `k` is the conductance parameter for diffusion
+/// - `iters` is the number of iterations diffusion is performed
+/// - `fftype` dictates the type of flux flow and it is an
+///    [enum](./enum.DiffusionEq.html)
+/// - `diff_kind` dictates the type of diffusion and it is an
+///   [enum](./enum.FluxFn.html)
+///
+/// # Return Values
+///
+/// Returns an anisotropically smoothed and noise-free image
+///
+/// ### References
+///
+///  - Pietro Perona and Jitendra Malik, `Scale-space and edge detection
+///    using anisotropic diffusion,` IEEE Transactions on Pattern Analysis
+///    Machine Intelligence, vol. 12, pp. 629-639, 1990.
+///  - R. Whitaker and X. Xue. `Variable-Conductance, Level-Set Curvature
+///    for Image Denoising`, International Conference on Image Processing,
+///    2001 pp. 142-145, Vol.3.
+pub fn anisotropic_diffusion<T>(
+    img: &Array<T>,
+    dt: f32,
+    k: f32,
+    iters: u32,
+    fftype: FluxFn,
+    diff_kind: DiffusionEq,
+) -> Array<T::AbsOutType>
+where
+    T: HasAfEnum + EdgeComputable,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_anisotropic_diffusion(
+            &mut temp as *mut af_array,
+            img.get(),
+            dt,
+            k,
+            iters,
+            fftype as c_uint,
+            diff_kind as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Segment image based on similar pixel characteristics
+///
+/// This filter is similar to [regions](./fn.regions.html) with additional criteria for
+/// segmentation. In regions, all connected pixels are considered to be a single component.
+/// In this variation of connected components, pixels having similar pixel statistics of the
+/// neighborhoods around a given set of seed points are grouped together.
+///
+/// The parameter `radius` determines the size of neighborhood around a seed point.
+///
+/// Mean and Variance are the pixel statistics that are computed across all neighborhoods around
+/// the given set of seed points. The pixels which are connected to seed points and lie in the
+/// confidence interval are grouped together. Given below is the confidence interval.
+///
+/// \begin{equation}
+///     [\mu - \alpha * \sigma, \mu + \alpha * \sigma]
+/// \end{equation}
+/// where
+///
+/// - $ \mu $ is the mean of the pixels in the seed neighborhood
+/// - $ \sigma^2 $ is the variance of the pixels in the seed neighborhood
+/// - $ \alpha $ is the multiplier used to control the width of the confidence interval.
+///
+/// This filter follows an iterative approach for fine tuning the segmentation. An initial
+/// segmenetation followed by a finite number `iterations` of segmentations are performed.
+/// The user provided parameter `iterations` is only a request and the algorithm can prempt
+/// the execution if variance approaches zero. The initial segmentation uses the mean and
+/// variance calculated from the neighborhoods of all the seed points. For subsequent
+/// segmentations, all pixels in the previous segmentation are used to re-calculate the mean
+/// and variance (as opposed to using the pixels in the neighborhood of the seed point).
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `seedx` contains the x coordinates of seeds in image coordinates
+/// - `seedy` contains the y coordinates of seeds in image coordinates
+/// - `radius` is the neighborhood region to be considered around each seed point
+/// - `multiplier` controls the threshold range computed from the mean and variance of seed point neighborhoods
+/// - `iterations` is the number of times the segmentation in performed
+/// - `segmented_value` is the value to which output array valid pixels are set to
+///
+/// # Return Values
+///
+/// Segmented(based on pixel characteristics) image(Array) with regions surrounding the seed points
+pub fn confidence_cc<InOutType>(
+    input: &Array<InOutType>,
+    seedx: &Array<u32>,
+    seedy: &Array<u32>,
+    radius: u32,
+    multiplier: u32,
+    iterations: u32,
+    segmented_val: f64,
+) -> Array<InOutType>
+where
+    InOutType: ConfidenceCCInput,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_confidence_cc(
+            &mut temp as *mut af_array,
+            input.get(),
+            seedx.get(),
+            seedy.get(),
+            radius,
+            multiplier,
+            iterations as i32,
+            segmented_val,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Iterative Deconvolution
+///
+/// The following table shows the iteration update equations of the respective
+/// deconvolution algorithms.
+///
+/// <table>
+/// <tr><th>Algorithm</th><th>Update Equation</th></tr>
+/// <tr>
+///     <td>LandWeber</td>
+///     <td>
+///         $ \hat{I}_{n} = \hat{I}_{n-1} + \alpha * P^T \otimes (I - P \otimes \hat{I}_{n-1}) $
+///     </td>
+/// </tr>
+/// <tr>
+///   <td>Richardson-Lucy</td>
+///   <td>
+///     $ \hat{I}_{n} = \hat{I}_{n-1} . ( \frac{I}{\hat{I}_{n-1} \otimes P} \otimes P^T ) $
+///   </td>
+/// </tr>
+/// </table>
+///
+/// where
+///
+/// - $ I $ is the observed(input/blurred) image
+/// - $ P $ is the point spread function
+/// - $ P^T $ is the transpose of point spread function
+/// - $ \hat{I}_{n} $ is the current iteration's updated image estimate
+/// - $ \hat{I}_{n-1} $ is the previous iteration's image estimate
+/// - $ \alpha $ is the relaxation factor
+/// - $ \otimes $ indicates the convolution operator
+///
+/// The type of output Array from deconvolution will be of type f64 if
+/// the input array type is f64. For other types, output type will be f32 type.
+/// Should the caller want to save the image to disk or require the values of output
+/// to be in a fixed range, that should be done by the caller explicitly.
+pub fn iterative_deconv<T>(
+    input: &Array<T>,
+    kernel: &Array<f32>,
+    iterations: u32,
+    relaxation_factor: f32,
+    algo: IterativeDeconvAlgo,
+) -> Array<T::AbsOutType>
+where
+    T: DeconvInput,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_iterative_deconv(
+            &mut temp as *mut af_array,
+            input.get(),
+            kernel.get(),
+            iterations,
+            relaxation_factor,
+            algo as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inverse deconvolution
+///
+/// This is a linear algorithm i.e. they are non-iterative in
+/// nature and usually faster than iterative deconvolution algorithms.
+///
+/// Depending on the values passed on to `algo` of type enum [InverseDeconvAlgo](./enum.inverse_deconv_algo.html),
+/// different equations are used to compute the final result.
+///
+/// #### Tikhonov's Deconvolution Method:
+///
+/// The update equation for this algorithm is as follows:
+///
+/// <div>
+/// \begin{equation}
+/// \hat{I}_{\omega} = \frac{ I_{\omega} * P^{*}_{\omega} } { |P_{\omega}|^2 + \gamma }
+/// \end{equation}
+/// </div>
+///
+/// where
+///
+/// - $ I_{\omega} $ is the observed(input/blurred) image in frequency domain
+/// - $ P_{\omega} $ is the point spread function in frequency domain
+/// - $ \gamma $ is a user defined regularization constant
+///
+/// The type of output Array from deconvolution will be double if the input array type is double.
+/// Otherwise, it will be float in rest of the cases. Should the caller want to save the image to
+/// disk or require the values of output to be in a fixed range, that should be done by the caller
+/// explicitly.
+pub fn inverse_deconv<T>(
+    input: &Array<T>,
+    kernel: &Array<f32>,
+    gamma: f32,
+    algo: InverseDeconvAlgo,
+) -> Array<T::AbsOutType>
+where
+    T: DeconvInput,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_inverse_deconv(
+            &mut temp as *mut af_array,
+            input.get(),
+            kernel.get(),
+            gamma,
+            algo as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/lapack/mod.rs.html b/src/arrayfire/lapack/mod.rs.html new file mode 100644 index 000000000..5bee3bec0 --- /dev/null +++ b/src/arrayfire/lapack/mod.rs.html @@ -0,0 +1,1059 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+
+use super::core::{
+    af_array, AfError, Array, FloatingPoint, HasAfEnum, MatProp, NormType, HANDLE_ERROR,
+};
+
+use libc::{c_double, c_int, c_uint};
+
+extern "C" {
+    fn af_svd(u: *mut af_array, s: *mut af_array, vt: *mut af_array, input: af_array) -> c_int;
+    fn af_svd_inplace(
+        u: *mut af_array,
+        s: *mut af_array,
+        vt: *mut af_array,
+        input: af_array,
+    ) -> c_int;
+    fn af_lu(
+        lower: *mut af_array,
+        upper: *mut af_array,
+        pivot: *mut af_array,
+        input: af_array,
+    ) -> c_int;
+    fn af_lu_inplace(pivot: *mut af_array, input: af_array, is_lapack_piv: bool) -> c_int;
+    fn af_qr(q: *mut af_array, r: *mut af_array, tau: *mut af_array, input: af_array) -> c_int;
+    fn af_qr_inplace(tau: *mut af_array, input: af_array) -> c_int;
+    fn af_cholesky(out: *mut af_array, info: *mut c_int, input: af_array, is_upper: bool) -> c_int;
+    fn af_cholesky_inplace(info: *mut c_int, input: af_array, is_upper: bool) -> c_int;
+    fn af_solve(x: *mut af_array, a: af_array, b: af_array, options: c_uint) -> c_int;
+    fn af_solve_lu(
+        x: *mut af_array,
+        a: af_array,
+        piv: af_array,
+        b: af_array,
+        options: c_uint,
+    ) -> c_int;
+    fn af_inverse(out: *mut af_array, input: af_array, options: c_uint) -> c_int;
+    fn af_rank(rank: *mut c_uint, input: af_array, tol: c_double) -> c_int;
+    fn af_det(det_real: *mut c_double, det_imag: *mut c_double, input: af_array) -> c_int;
+    fn af_norm(
+        out: *mut c_double,
+        input: af_array,
+        ntype: c_uint,
+        p: c_double,
+        q: c_double,
+    ) -> c_int;
+    fn af_is_lapack_available(out: *mut bool) -> c_int;
+    fn af_pinverse(out: *mut af_array, input: af_array, tol: c_double, options: c_uint) -> c_int;
+}
+
+/// Perform Singular Value Decomposition
+///
+/// This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S
+/// such that
+///
+/// A = U∗S∗Vt
+///
+/// If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M
+/// x N
+///
+/// # Parameters
+///
+/// - `in` is the input matrix
+///
+/// # Return Values
+///
+/// A triplet of Arrays.
+///
+/// The first Array is the output array containing U
+///
+/// The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix))
+///
+/// The third Array is the output array containing V ^ H
+pub fn svd<T>(input: &Array<T>) -> (Array<T>, Array<T::BaseType>, Array<T>)
+where
+    T: HasAfEnum + FloatingPoint,
+    T::BaseType: HasAfEnum,
+{
+    unsafe {
+        let mut u: af_array = std::ptr::null_mut();
+        let mut s: af_array = std::ptr::null_mut();
+        let mut vt: af_array = std::ptr::null_mut();
+        let err_val = af_svd(
+            &mut u as *mut af_array,
+            &mut s as *mut af_array,
+            &mut vt as *mut af_array,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (u.into(), s.into(), vt.into())
+    }
+}
+
+/// Perform Singular Value Decomposition inplace
+///
+/// This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S
+/// such that
+///
+/// A = U∗S∗Vt
+///
+/// If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M
+/// x N
+///
+/// # Parameters
+///
+/// - `in` is the input/output matrix. This will contain random data after the function call is
+/// complete.
+///
+/// # Return Values
+///
+/// A triplet of Arrays.
+///
+/// The first Array is the output array containing U
+///
+/// The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix))
+///
+/// The third Array is the output array containing V ^ H
+pub fn svd_inplace<T>(input: &mut Array<T>) -> (Array<T>, Array<T::BaseType>, Array<T>)
+where
+    T: HasAfEnum + FloatingPoint,
+    T::BaseType: HasAfEnum,
+{
+    unsafe {
+        let mut u: af_array = std::ptr::null_mut();
+        let mut s: af_array = std::ptr::null_mut();
+        let mut vt: af_array = std::ptr::null_mut();
+        let err_val = af_svd_inplace(
+            &mut u as *mut af_array,
+            &mut s as *mut af_array,
+            &mut vt as *mut af_array,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (u.into(), s.into(), vt.into())
+    }
+}
+
+/// Perform LU decomposition
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+///
+/// # Return Values
+///
+/// A triplet of Arrays.
+///
+/// The first Array will contain the lower triangular matrix of the LU decomposition.
+///
+/// The second Array will contain the lower triangular matrix of the LU decomposition.
+///
+/// The third Array will contain the permutation indices to map the input to the decomposition.
+pub fn lu<T>(input: &Array<T>) -> (Array<T>, Array<T>, Array<i32>)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut lower: af_array = std::ptr::null_mut();
+        let mut upper: af_array = std::ptr::null_mut();
+        let mut pivot: af_array = std::ptr::null_mut();
+        let err_val = af_lu(
+            &mut lower as *mut af_array,
+            &mut upper as *mut af_array,
+            &mut pivot as *mut af_array,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (lower.into(), upper.into(), pivot.into())
+    }
+}
+
+/// Perform inplace LU decomposition
+///
+/// # Parameters
+///
+/// - `input` contains the input matrix on entry and packed LU decomposition on exit
+/// - `is_lapack_pic` specified if the pivot is returned in original LAPACK compliant format
+///
+/// # Return Values
+///
+/// An Array with permutation indices to map the input to the decomposition. Since, the input
+/// matrix is modified in place, only pivot values are returned.
+pub fn lu_inplace<T>(input: &mut Array<T>, is_lapack_piv: bool) -> Array<i32>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut pivot: af_array = std::ptr::null_mut();
+        let err_val = af_lu_inplace(&mut pivot as *mut af_array, input.get(), is_lapack_piv);
+        HANDLE_ERROR(AfError::from(err_val));
+        pivot.into()
+    }
+}
+
+/// Perform QR decomposition
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+///
+/// # Return Values
+///
+/// A triplet of Arrays.
+///
+/// The first Array is the orthogonal matrix from QR decomposition
+///
+/// The second Array is the upper triangular matrix from QR decomposition
+///
+/// The third Array will contain additional information needed for solving a least squares problem
+/// using q and r
+pub fn qr<T>(input: &Array<T>) -> (Array<T>, Array<T>, Array<T>)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut q: af_array = std::ptr::null_mut();
+        let mut r: af_array = std::ptr::null_mut();
+        let mut tau: af_array = std::ptr::null_mut();
+        let err_val = af_qr(
+            &mut q as *mut af_array,
+            &mut r as *mut af_array,
+            &mut tau as *mut af_array,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (q.into(), r.into(), tau.into())
+    }
+}
+
+/// Perform inplace QR decomposition
+///
+/// # Parameters
+///
+/// - `input` contains the input matrix on entry, and packed QR decomposition on exit
+///
+/// # Return Values
+///
+/// An Array with additional information needed for unpacking the data.
+pub fn qr_inplace<T>(input: &mut Array<T>) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut tau: af_array = std::ptr::null_mut();
+        let err_val = af_qr_inplace(&mut tau as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        tau.into()
+    }
+}
+
+/// Perform Cholesky decomposition
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+/// - `is_upper` is a boolean to indicate if the output has to be upper or lower triangular matrix
+///
+/// # Return Values
+///
+/// A tuple of an Array and signed 32-bit integer.
+///
+/// The Array contains the triangular matrix (multiply it with conjugate transpose to reproduce the input).
+///
+/// If the integer is 0, it means the cholesky decomposition passed. Otherwise, it will contain the rank at
+/// which the decomposition failed.
+pub fn cholesky<T>(input: &Array<T>, is_upper: bool) -> (Array<T>, i32)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let mut info: i32 = 0;
+        let err_val = af_cholesky(
+            &mut temp as *mut af_array,
+            &mut info as *mut c_int,
+            input.get(),
+            is_upper,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (temp.into(), info)
+    }
+}
+
+/// Perform inplace Cholesky decomposition
+///
+/// # Parameters
+///
+/// - `input` contains the input matrix on entry, and triangular matrix on exit.
+/// - `is_upper` is a boolean to indicate if the output has to be upper or lower triangular matrix
+///
+/// # Return Values
+///
+/// A signed 32-bit integer. If the integer is 0, it means the cholesky decomposition passed. Otherwise,
+/// it will contain the rank at which the decomposition failed.
+pub fn cholesky_inplace<T>(input: &mut Array<T>, is_upper: bool) -> i32
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let mut info: i32 = 0;
+    unsafe {
+        let err_val = af_cholesky_inplace(&mut info as *mut c_int, input.get(), is_upper);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    info
+}
+
+/// Solve a system of equations
+///
+/// # Parameters
+///
+/// - `a` is the coefficient matrix
+/// - `b` has the measured values
+/// - `options` determine the various properties of matrix a
+///
+/// The `options` parameter currently needs to be either `NONE`, `LOWER` or `UPPER`, other values are not supported yet.
+///
+/// # Return Values
+///
+/// An Array which is the matrix of unknown variables
+pub fn solve<T>(a: &Array<T>, b: &Array<T>, options: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_solve(
+            &mut temp as *mut af_array,
+            a.get(),
+            b.get(),
+            options as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Solve a system of equations
+///
+/// # Parameters
+///
+/// - `a` is the output matrix from packed LU decomposition of the coefficient matrix
+/// - `piv` is the pivot array from packed LU decomposition of the coefficient matrix
+/// - `b` has the measured values
+/// - `options` determine the various properties of matrix a
+///
+/// The `options` parameter currently needs to be `NONE`, other values are not supported yet.
+///
+/// # Return Values
+///
+/// An Array which is the matrix of unknown variables
+pub fn solve_lu<T>(a: &Array<T>, piv: &Array<i32>, b: &Array<T>, options: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_solve_lu(
+            &mut temp as *mut af_array,
+            a.get(),
+            piv.get(),
+            b.get(),
+            options as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Compute inverse of a matrix
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+/// - `options` determine various properties of input matrix
+///
+/// The parameter `options` currently take only the value `NONE`.
+///
+/// # Return Values
+///
+/// An Array with values of the inverse of input matrix.
+pub fn inverse<T>(input: &Array<T>, options: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_inverse(&mut temp as *mut af_array, input.get(), options as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Find rank of a matrix
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+/// - `tol` is the tolerance value
+///
+/// # Return Values
+///
+/// An unsigned 32-bit integer which is the rank of the input matrix.
+pub fn rank<T>(input: &Array<T>, tol: f64) -> u32
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let mut temp: u32 = 0;
+    unsafe {
+        let err_val = af_rank(&mut temp as *mut c_uint, input.get(), tol);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    temp
+}
+
+/// Find the determinant of the matrix
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+///
+/// # Return Values
+///
+/// A tuple of 32-bit floating point values.
+///
+/// If the input matrix is non-complex type, only first values of tuple contains the result.
+pub fn det<T>(input: &Array<T>) -> (f64, f64)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_det(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (real, imag)
+}
+
+/// Find the norm of a matrix
+///
+/// # Parameters
+///
+/// - `input` is the input matrix
+/// - `ntype` is specifies the required norm type using enum [NormType](./enum.NormType.html)
+/// - `p` specifies the value of *P* when `ntype` is one of VECTOR_P, MATRIX_L_PQ. It is ignored
+/// for other values of `ntype`
+/// - `q` specifies the value of *Q* when `ntype` is MATRIX_L_PQ. This parameter is ignored if
+/// `ntype` is anything else.
+///
+/// # Return Values
+///
+/// A 64-bit floating point value that contains the norm of input matrix.
+pub fn norm<T>(input: &Array<T>, ntype: NormType, p: f64, q: f64) -> f64
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let mut out: f64 = 0.0;
+    unsafe {
+        let err_val = af_norm(
+            &mut out as *mut c_double,
+            input.get(),
+            ntype as c_uint,
+            p,
+            q,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    out
+}
+
+/// Function to check if lapack support is available
+///
+/// # Parameters
+///
+/// None
+///
+/// # Return Values
+///
+/// Return a boolean indicating if ArrayFire was compiled with lapack support
+pub fn is_lapack_available() -> bool {
+    let mut temp: bool = false;
+    unsafe {
+        af_is_lapack_available(&mut temp as *mut bool);
+    }
+    temp
+}
+
+/// Psuedo Inverse of Matrix
+///
+/// # Parameters
+///
+/// - `input` is input matrix
+/// - `tolerance` defines the lower threshold for singular values from SVD
+/// - `option` must be [MatProp::NONE](./enum.MatProp.html) (more options might be supported in the future)
+///
+/// Notes:
+///
+/// - Tolerance is not the actual lower threshold, but it is passed in as a
+///   parameter to the calculation of the actual threshold relative to the shape and contents of input.
+/// - First, try setting tolerance to 1e-6 for single precision and 1e-12 for double.
+///
+/// # Return
+///
+/// Pseudo Inverse matrix for the input matrix
+pub fn pinverse<T>(input: &Array<T>, tolerance: f64, option: MatProp) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut out: af_array = std::ptr::null_mut();
+        let err_val = af_pinverse(
+            &mut out as *mut af_array,
+            input.get(),
+            tolerance,
+            option as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        out.into()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/lib.rs.html b/src/arrayfire/lib.rs.html new file mode 100644 index 000000000..637a337dc --- /dev/null +++ b/src/arrayfire/lib.rs.html @@ -0,0 +1,201 @@ +lib.rs - source + + + +
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
+//! ArrayFire is a high performance software library for parallel computing with an easy-to-use API.
+//! ArrayFire abstracts away much of the details of programming parallel architectures by providing
+//! a high-level container object, the [Array](./struct.Array.html), that represents data stored on
+//! a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write
+//! massively parallel applications in a high-level language where they need not be concerned about
+//! low-level optimizations that are frequently required to achieve high throughput on most parallel
+//! architectures.
+
+//! This crate provides Rust bindings for the ArrayFire library. Given below table shows the rust
+//! bindings compatability with ArrayFire upstream.  If you find any bugs, please report them on
+//! [github](https://github.com/arrayfire/arrayfire-rust/issues).
+//!
+//! | arrayfire-rust crate | ArrayFire Upstream |
+//! |:--------------------:|:------------------:|
+//! |         M.m.p1       |      M.m.p2        |
+//!
+//! Only, Major(M) & Minor(m) version numbers need to match. *p1* and *p2* are patch/fix updates
+//! for `arrayfire-rust` & `ArrayFire` respectively, and they don't need to match.
+//!
+//! Please go through our [tutorials](http://arrayfire.org/arrayfire-rust/book/index.html) book for
+//! more explanations on how to use ArrayFire to speedup your code.
+
+#![doc(
+    html_logo_url = "https://www.arrayfire.com/logos/arrayfire_logo_symbol.png",
+    html_favicon_url = "https://www.arrayfire.com/logos/arrayfire.ico",
+    html_root_url = "https://arrayfire.org/arrayfire-rust/arrayfire/index.html"
+)]
+#![warn(missing_docs)]
+#![allow(non_camel_case_types)]
+
+#[macro_use]
+extern crate lazy_static;
+
+pub use crate::core::*;
+mod core;
+
+#[cfg(feature = "algorithm")]
+pub use crate::algorithm::*;
+#[cfg(feature = "algorithm")]
+mod algorithm;
+
+#[cfg(feature = "blas")]
+pub use crate::blas::*;
+#[cfg(feature = "blas")]
+mod blas;
+
+#[cfg(feature = "graphics")]
+pub use crate::graphics::Window;
+#[cfg(feature = "graphics")]
+mod graphics;
+
+#[cfg(feature = "image")]
+pub use crate::image::*;
+#[cfg(feature = "image")]
+mod image;
+
+#[cfg(feature = "lapack")]
+pub use crate::lapack::*;
+#[cfg(feature = "lapack")]
+mod lapack;
+
+#[cfg(feature = "ml")]
+pub use crate::ml::*;
+#[cfg(feature = "ml")]
+mod ml;
+
+#[cfg(feature = "signal")]
+pub use crate::signal::*;
+#[cfg(feature = "signal")]
+mod signal;
+
+#[cfg(feature = "sparse")]
+pub use crate::sparse::*;
+#[cfg(feature = "sparse")]
+mod sparse;
+
+#[cfg(feature = "statistics")]
+pub use crate::statistics::*;
+#[cfg(feature = "statistics")]
+mod statistics;
+
+#[cfg(feature = "vision")]
+pub use crate::vision::*;
+#[cfg(feature = "vision")]
+mod vision;
+
+// headers that are not exposed through rust wrapper are given follows:
+// compatible.h
+// constants.h
+// complex.h
+// cuda.h
+// opencl.h
+
+
\ No newline at end of file diff --git a/src/arrayfire/ml/mod.rs.html b/src/arrayfire/ml/mod.rs.html new file mode 100644 index 000000000..f6801cfad --- /dev/null +++ b/src/arrayfire/ml/mod.rs.html @@ -0,0 +1,297 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+
+use super::core::{
+    af_array, dim_t, AfError, Array, ConvGradientType, Dim4, HasAfEnum, RealFloating, HANDLE_ERROR,
+};
+
+use libc::{c_int, c_uint};
+
+extern "C" {
+    fn af_convolve2_nn(
+        out: *mut af_array,
+        signal: af_array,
+        filter: af_array,
+        stride_dims: c_uint,
+        strides: *const dim_t,
+        padding_dim: c_uint,
+        paddings: *const dim_t,
+        dilation_dim: c_uint,
+        dilations: *const dim_t,
+    ) -> c_int;
+
+    fn af_convolve2_gradient_nn(
+        out: *mut af_array,
+        incoming_gradient: af_array,
+        original_signal: af_array,
+        original_filter: af_array,
+        convolved_output: af_array,
+        stride_dims: c_uint,
+        strides: *const dim_t,
+        padding_dims: c_uint,
+        paddings: *const dim_t,
+        dilation_dims: c_uint,
+        dilations: *const dim_t,
+        grad_type: c_uint,
+    ) -> c_int;
+}
+
+/// Convolution Integral for two dimensional data
+///
+/// This version of convolution is consistent with the machine learning formulation
+/// that will spatially convolve a filter on 2-dimensions against a signal. Multiple
+/// signals and filters can be batched against each other. Furthermore, the signals
+/// and filters can be multi-dimensional however their dimensions must match. Usually,
+/// this is the forward pass convolution in ML
+///
+/// Example:
+///
+/// Signals with dimensions: d0 x d1 x d2 x Ns
+///
+/// Filters with dimensions: d0 x d1 x d2 x Nf
+///
+/// Resulting Convolution: d0 x d1 x Nf x Ns
+///
+/// # Parameters
+///
+/// - `signal` is the input signal
+/// - `filter` is convolution filter
+/// - `strides` are distance between consecutive elements along each dimension for original convolution
+/// - `padding` specifies padding width along each dimension for original convolution
+/// - `dilation` specifies filter dilation along each dimension for original convolution
+///
+/// # Return Values
+///
+/// Convolved Array
+pub fn convolve2_nn<T>(
+    signal: &Array<T>,
+    filter: &Array<T>,
+    strides: Dim4,
+    padding: Dim4,
+    dilation: Dim4,
+) -> Array<T>
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_convolve2_nn(
+            &mut temp as *mut af_array,
+            signal.get(),
+            filter.get(),
+            strides.ndims() as c_uint,
+            strides.get().as_ptr() as *const dim_t,
+            padding.ndims() as c_uint,
+            padding.get().as_ptr() as *const dim_t,
+            dilation.ndims() as c_uint,
+            dilation.get().as_ptr() as *const dim_t,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Backward pass gradient of 2D convolution
+///
+/// # Parameters
+///
+/// - `incoming_gradient` gradients to be distributed in backwards pass
+/// - `original_signal` input signal to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N )
+/// - `original_filter` input filter to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N )
+/// - `convolved_output` output from forward pass of convolution
+/// - `strides` are distance between consecutive elements along each dimension for original convolution
+/// - `padding` specifies padding width along each dimension for original convolution
+/// - `dilation` specifies filter dilation along each dimension for original convolution
+/// - `grad_type` specifies which gradient to return
+///
+/// # Return Values
+///
+/// Gradient Array w.r.t input generated from [convolve2_nn](./fn.convolve2_nn.html)
+#[allow(clippy::too_many_arguments)]
+pub fn convolve2_gradient_nn<T>(
+    incoming_grad: &Array<T>,
+    original_signal: &Array<T>,
+    original_filter: &Array<T>,
+    convolved_output: &Array<T>,
+    strides: Dim4,
+    padding: Dim4,
+    dilation: Dim4,
+    grad_type: ConvGradientType,
+) -> Array<T>
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_convolve2_gradient_nn(
+            &mut temp as *mut af_array,
+            incoming_grad.get(),
+            original_signal.get(),
+            original_filter.get(),
+            convolved_output.get(),
+            strides.ndims() as c_uint,
+            strides.get().as_ptr() as *const dim_t,
+            padding.ndims() as c_uint,
+            padding.get().as_ptr() as *const dim_t,
+            dilation.ndims() as c_uint,
+            dilation.get().as_ptr() as *const dim_t,
+            grad_type as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/signal/mod.rs.html b/src/arrayfire/signal/mod.rs.html new file mode 100644 index 000000000..d41b66b5b --- /dev/null +++ b/src/arrayfire/signal/mod.rs.html @@ -0,0 +1,2273 @@ +mod.rs - source + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+
+use super::core::{
+    af_array, dim_t, AfError, Array, ComplexFloating, ConvDomain, ConvMode, FloatingPoint,
+    HasAfEnum, InterpType, RealFloating, HANDLE_ERROR,
+};
+
+use libc::{c_double, c_float, c_int, c_uint, size_t};
+use num::Complex;
+
+extern "C" {
+    fn af_approx1(
+        out: *mut af_array,
+        inp: af_array,
+        pos: af_array,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx1_v2(
+        out: *mut af_array,
+        inp: af_array,
+        pos: af_array,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx1_uniform(
+        out: *mut af_array,
+        inp: af_array,
+        pos: af_array,
+        interp_dim: c_int,
+        idx_start: c_double,
+        idx_step: c_double,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx1_uniform_v2(
+        out: *mut af_array,
+        inp: af_array,
+        pos: af_array,
+        interp_dim: c_int,
+        idx_start: c_double,
+        idx_step: c_double,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx2(
+        out: *mut af_array,
+        inp: af_array,
+        pos0: af_array,
+        pos1: af_array,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx2_v2(
+        out: *mut af_array,
+        inp: af_array,
+        pos0: af_array,
+        pos1: af_array,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx2_uniform(
+        out: *mut af_array,
+        inp: af_array,
+        pos0: af_array,
+        interp_dim0: c_int,
+        idx_start_dim0: c_double,
+        idx_step_dim0: c_double,
+        pos1: af_array,
+        interp_dim1: c_int,
+        idx_start_dim1: c_double,
+        idx_step_dim1: c_double,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_approx2_uniform_v2(
+        out: *mut af_array,
+        inp: af_array,
+        pos0: af_array,
+        interp_dim0: c_int,
+        idx_start_dim0: c_double,
+        idx_step_dim0: c_double,
+        pos1: af_array,
+        interp_dim1: c_int,
+        idx_start_dim1: c_double,
+        idx_step_dim1: c_double,
+        method: c_uint,
+        off_grid: c_float,
+    ) -> c_int;
+
+    fn af_set_fft_plan_cache_size(cache_size: size_t) -> c_int;
+
+    fn af_fft(out: *mut af_array, arr: af_array, nfac: c_double, odim0: dim_t) -> c_int;
+
+    fn af_fft2(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        odim0: dim_t,
+        odim1: dim_t,
+    ) -> c_int;
+
+    fn af_fft3(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        odim0: dim_t,
+        odim1: dim_t,
+        odim2: dim_t,
+    ) -> c_int;
+
+    fn af_ifft(out: *mut af_array, arr: af_array, nfac: c_double, odim0: dim_t) -> c_int;
+
+    fn af_ifft2(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        odim0: dim_t,
+        odim1: dim_t,
+    ) -> c_int;
+
+    fn af_ifft3(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        odim0: dim_t,
+        odim1: dim_t,
+        odim2: dim_t,
+    ) -> c_int;
+
+    fn af_fft_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+    fn af_fft2_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+    fn af_fft3_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+    fn af_ifft_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+    fn af_ifft2_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+    fn af_ifft3_inplace(arr: *mut af_array, nfac: c_double) -> c_int;
+
+    fn af_fft_r2c(out: *mut af_array, arr: af_array, nfac: c_double, pad0: dim_t) -> c_int;
+    fn af_fft2_r2c(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        pad0: dim_t,
+        pad1: dim_t,
+    ) -> c_int;
+    fn af_fft3_r2c(
+        out: *mut af_array,
+        arr: af_array,
+        nfac: c_double,
+        pad0: dim_t,
+        pad1: dim_t,
+        pad2: dim_t,
+    ) -> c_int;
+
+    fn af_fft_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int;
+    fn af_fft2_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int;
+    fn af_fft3_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int;
+
+    fn af_convolve1(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int;
+    fn af_convolve2(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int;
+    fn af_convolve3(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int;
+    fn af_convolve2_sep(
+        o: *mut af_array,
+        c: af_array,
+        r: af_array,
+        s: af_array,
+        m: c_uint,
+    ) -> c_int;
+    fn af_fft_convolve1(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int;
+    fn af_fft_convolve2(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int;
+    fn af_fft_convolve3(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int;
+    fn af_fir(out: *mut af_array, b: af_array, x: af_array) -> c_int;
+    fn af_iir(out: *mut af_array, b: af_array, a: af_array, x: af_array) -> c_int;
+}
+
+/// Perform signal interpolation for 1d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `pos` Array contains the interpolation locations
+/// - `method` indicates the type of interpolation method that be used. It is of type enum
+/// [InterpType](./enum.InterpType.html)
+/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds
+///
+/// # Return Values
+///
+/// An Array with interpolated values
+pub fn approx1<T, P>(
+    input: &Array<T>,
+    pos: &Array<P>,
+    method: InterpType,
+    off_grid: f32,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_approx1(
+            &mut temp as *mut af_array,
+            input.get(),
+            pos.get(),
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Same as [approx1](./fn.approx1.html) but uses existing Array as output
+pub fn approx1_v2<T, P>(
+    output: &mut Array<T>,
+    input: &Array<T>,
+    pos: &Array<P>,
+    method: InterpType,
+    off_grid: f32,
+) where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let err_val = af_approx1_v2(
+            output.get() as *mut af_array,
+            input.get(),
+            pos.get(),
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Perform signal interpolation for 1d signals along specified dimension
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `pos` Array contains the interpolation locations
+/// - `interp_dim` is the dimension along which interpolation is performed
+/// - `start` is the first index along `interp_dim`
+/// - `step` is the uniform spacing value between subsequent indices along `interp_dim`
+/// - `method` indicates the type of interpolation method that be used. It is of type enum
+/// [InterpType](./enum.InterpType.html)
+/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds
+///
+/// # Return Values
+///
+/// An Array with interpolated values
+pub fn approx1_uniform<T, P>(
+    input: &Array<T>,
+    pos: &Array<P>,
+    interp_dim: i32,
+    start: f64,
+    step: f64,
+    method: InterpType,
+    off_grid: f32,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_approx1_uniform(
+            &mut temp as *mut af_array,
+            input.get(),
+            pos.get(),
+            interp_dim,
+            start,
+            step,
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Same as [approx1_uniform](./fn.approx1_uniform.html) but uses existing Array as output
+#[allow(clippy::too_many_arguments)]
+pub fn approx1_uniform_v2<T, P>(
+    output: &mut Array<T>,
+    input: &Array<T>,
+    pos: &Array<P>,
+    interp_dim: i32,
+    start: f64,
+    step: f64,
+    method: InterpType,
+    off_grid: f32,
+) where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let err_val = af_approx1_uniform_v2(
+            output.get() as *mut af_array,
+            input.get(),
+            pos.get(),
+            interp_dim,
+            start,
+            step,
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Perform signal interpolation for 2d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `pos0` Array contains the interpolation locations for first dimension
+/// - `pos1` Array contains the interpolation locations for second dimension
+/// - `method` indicates the type of interpolation method that be used. It is of type enum
+/// [InterpType](./enum.InterpType.html)
+/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds
+///
+/// # Return Values
+///
+/// An Array with interpolated values
+pub fn approx2<T, P>(
+    input: &Array<T>,
+    pos0: &Array<P>,
+    pos1: &Array<P>,
+    method: InterpType,
+    off_grid: f32,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_approx2(
+            &mut temp as *mut af_array,
+            input.get(),
+            pos0.get(),
+            pos1.get(),
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Same as [approx2](./fn.approx2.html) but uses existing Array as output
+pub fn approx2_v2<T, P>(
+    output: &mut Array<T>,
+    input: &Array<T>,
+    pos0: &Array<P>,
+    pos1: &Array<P>,
+    method: InterpType,
+    off_grid: f32,
+) where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let err_val = af_approx2_v2(
+            output.get() as *mut af_array,
+            input.get(),
+            pos0.get(),
+            pos1.get(),
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Perform signal interpolation for 2d signals along a specified dimension
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `pos0` Array contains the interpolation locations for first dimension
+/// - `interp_dim0` is the dimension along which interpolation is performed
+/// - `start0` is the first index along `interp_dim0`
+/// - `step0` is the uniform spacing value between subsequent indices along `interp_dim0`
+/// - `pos1` Array contains the interpolation locations for second dimension
+/// - `interp_dim0` is the dimension along which interpolation is performed
+/// - `start0` is the first index along `interp_dim1`
+/// - `step0` is the uniform spacing value between subsequent indices along `interp_dim1`
+/// - `method` indicates the type of interpolation method that be used. It is of type enum
+/// [InterpType](./enum.InterpType.html)
+/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds
+///
+/// # Return Values
+///
+/// An Array with interpolated values
+#[allow(clippy::too_many_arguments)]
+pub fn approx2_uniform<T, P>(
+    input: &Array<T>,
+    pos0: &Array<P>,
+    interp_dim0: i32,
+    start0: f64,
+    step0: f64,
+    pos1: &Array<P>,
+    interp_dim1: i32,
+    start1: f64,
+    step1: f64,
+    method: InterpType,
+    off_grid: f32,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_approx2_uniform(
+            &mut temp as *mut af_array,
+            input.get(),
+            pos0.get(),
+            interp_dim0,
+            start0,
+            step0,
+            pos1.get(),
+            interp_dim1,
+            start1,
+            step1,
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Same as [approx2_uniform](./fn.approx2_uniform.html) but uses existing Array as output
+#[allow(clippy::too_many_arguments)]
+pub fn approx2_uniform_v2<T, P>(
+    output: &mut Array<T>,
+    input: &Array<T>,
+    pos0: &Array<P>,
+    interp_dim0: i32,
+    start0: f64,
+    step0: f64,
+    pos1: &Array<P>,
+    interp_dim1: i32,
+    start1: f64,
+    step1: f64,
+    method: InterpType,
+    off_grid: f32,
+) where
+    T: HasAfEnum + FloatingPoint,
+    P: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let err_val = af_approx2_uniform_v2(
+            output.get() as *mut af_array,
+            input.get(),
+            pos0.get(),
+            interp_dim0,
+            start0,
+            step0,
+            pos1.get(),
+            interp_dim1,
+            start1,
+            step1,
+            method as c_uint,
+            off_grid,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Set fft plan cache size
+///
+/// Though this is a low overhead function, it is advised not to change
+/// the fft plan cache size a mid program execution unless that is what
+/// you intend to do.
+pub fn set_fft_plan_cache_size(cache_size: usize) {
+    unsafe {
+        let err_val = af_set_fft_plan_cache_size(cache_size as size_t);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// Fast fourier transform for 1d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signals - used for either truncating or padding the input
+/// signals
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn fft<T>(input: &Array<T>, norm_factor: f64, odim0: i64) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft(&mut temp as *mut af_array, input.get(), norm_factor, odim0);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Fast fourier transform for 2d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input
+/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn fft2<T>(
+    input: &Array<T>,
+    norm_factor: f64,
+    odim0: i64,
+    odim1: i64,
+) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft2(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            odim0,
+            odim1,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Fast fourier transform for 3d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input
+/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input
+/// - `odim2` is the length of output signal third dimension - used for either truncating or padding the input
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn fft3<T>(
+    input: &Array<T>,
+    norm_factor: f64,
+    odim0: i64,
+    odim1: i64,
+    odim2: i64,
+) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft3(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            odim0,
+            odim1,
+            odim2,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inverse fast fourier transform for 1d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signals - used for either truncating or padding the input
+/// signals
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn ifft<T>(input: &Array<T>, norm_factor: f64, odim0: i64) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_ifft(&mut temp as *mut af_array, input.get(), norm_factor, odim0);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inverse fast fourier transform for 2d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input
+/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn ifft2<T>(
+    input: &Array<T>,
+    norm_factor: f64,
+    odim0: i64,
+    odim1: i64,
+) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_ifft2(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            odim0,
+            odim1,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Inverse fast fourier transform for 3d signals
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor with which the input is scaled before the
+/// transformation is applied
+/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input
+/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input
+/// - `odim2` is the length of output signal third dimension - used for either truncating or padding the input
+///
+/// # Return Values
+///
+/// Transformed Array
+pub fn ifft3<T>(
+    input: &Array<T>,
+    norm_factor: f64,
+    odim0: i64,
+    odim1: i64,
+    odim2: i64,
+) -> Array<T::ComplexOutType>
+where
+    T: HasAfEnum + FloatingPoint,
+    <T as HasAfEnum>::ComplexOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_ifft3(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            odim0,
+            odim1,
+            odim2,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! conv_func_def {
+    ($doc_str: expr, $fn_name:ident, $ffi_name: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `signal` is the input signal
+        /// - `filter` is the signal that shall be flipped for convolution operation
+        /// - `mode` indicates if the convolution should be expanded or not(where output size
+        /// equals input). It takes a value of type [ConvMode](./enum.ConvMode.html)
+        /// - `domain` indicates if the convolution should be performed in frequencey or spatial
+        /// domain. It takes a value of type [ConvDomain](./enum.ConvDomain.html)
+        ///
+        ///# Return Values
+        ///
+        /// Convolved Array
+        pub fn $fn_name<T, F>(
+            signal: &Array<T>,
+            filter: &Array<F>,
+            mode: ConvMode,
+            domain: ConvDomain,
+        ) -> Array<T>
+        where
+            T: HasAfEnum,
+            F: HasAfEnum,
+        {
+            unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array,
+                    signal.get(),
+                    filter.get(),
+                    mode as c_uint,
+                    domain as c_uint,
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+conv_func_def!("1d convolution", convolve1, af_convolve1);
+conv_func_def!("2d convolution", convolve2, af_convolve2);
+conv_func_def!("3d convolution", convolve3, af_convolve3);
+
+/// Separable convolution for 2d signals
+///
+/// # Parameters
+///
+/// - `cfilt` is the filter to be applied along coloumns
+/// - `rfilt` is the filter to be applied along rows
+/// - `signal` is the input signal
+/// - `mode` indicates if the convolution should be expanded or not(where output size equals input)
+///
+/// # Return Values
+///
+/// The convolved Array
+pub fn convolve2_sep<T, F>(
+    cfilt: &Array<F>,
+    rfilt: &Array<F>,
+    signal: &Array<T>,
+    mode: ConvMode,
+) -> Array<T>
+where
+    T: HasAfEnum,
+    F: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_convolve2_sep(
+            &mut temp as *mut af_array,
+            cfilt.get(),
+            rfilt.get(),
+            signal.get(),
+            mode as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! fft_conv_func_def {
+    ($doc_str: expr, $fn_name:ident, $ffi_name: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `signal` is the input signal
+        /// - `filter` is the signal that shall be used for convolution operation
+        /// - `mode` indicates if the convolution should be expanded or not(where output size
+        /// equals input). It takes values of type [ConvMode](./enum.ConvMode.html)
+        ///
+        ///# Return Values
+        ///
+        /// Convolved Array
+        pub fn $fn_name<T, F>(signal: &Array<T>, filter: &Array<F>, mode: ConvMode) -> Array<T>
+        where
+            T: HasAfEnum,
+            F: HasAfEnum,
+        {
+            unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(
+                    &mut temp as *mut af_array, signal.get(), filter.get(), mode as c_uint);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+fft_conv_func_def!(
+    "1d convolution using fast-fourier transform",
+    fft_convolve1,
+    af_fft_convolve1
+);
+fft_conv_func_def!(
+    "2d convolution using fast-fourier transform",
+    fft_convolve2,
+    af_fft_convolve2
+);
+fft_conv_func_def!(
+    "3d convolution using fast-fourier transform",
+    fft_convolve3,
+    af_fft_convolve3
+);
+
+/// Finite impulse filter
+///
+/// # Parameters
+///
+/// - `b` is the Array containing the coefficients of the filter
+/// - `x` is the input signal to filter
+///
+/// # Return Values
+///
+/// Filtered Array
+pub fn fir<B, X>(b: &Array<B>, x: &Array<X>) -> Array<X>
+where
+    B: HasAfEnum,
+    X: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fir(&mut temp as *mut af_array, b.get(), x.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Infinite impulse response filter
+///
+/// # Parameters
+///
+/// - `b` is the Array containing the feedforward coefficients
+/// - `a` is the Array containing the feedback coefficients
+/// - `x` is the input signal to filter
+///
+/// # Return Values
+///
+/// Filtered Array
+pub fn iir<T: HasAfEnum>(b: &Array<T>, a: &Array<T>, x: &Array<T>) -> Array<T> {
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_iir(&mut temp as *mut af_array, b.get(), a.get(), x.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// In place 1d dimensional Fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn fft_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_fft_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// In place 2d dimensional Fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn fft2_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_fft2_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// In place 3d dimensional Fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn fft3_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_fft3_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// In place 1d dimensional inverse fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn ifft_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_ifft_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// In place 2d dimensional inverse fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn ifft2_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_ifft2_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// In place 3d dimensional inverse fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor
+pub fn ifft3_inplace<T>(input: &mut Array<T>, norm_factor: f64)
+where
+    T: HasAfEnum + ComplexFloating,
+{
+    unsafe {
+        let err_val = af_ifft3_inplace(input.get() as *mut af_array, norm_factor);
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+}
+
+/// 1d Real to Complex fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `pad0` is the padding along 0th dimension of Array
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft_r2c<T>(input: &Array<T>, norm_factor: f64, pad0: i64) -> Array<Complex<T>>
+where
+    T: HasAfEnum + RealFloating,
+    Complex<T>: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft_r2c(&mut temp as *mut af_array, input.get(), norm_factor, pad0);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// 2d Real to Complex fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `pad0` is the padding along 0th dimension of Array
+/// - `pad1` is the padding along 1st dimension of Array
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft2_r2c<T>(input: &Array<T>, norm_factor: f64, pad0: i64, pad1: i64) -> Array<Complex<T>>
+where
+    T: HasAfEnum + RealFloating,
+    Complex<T>: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft2_r2c(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            pad0,
+            pad1,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// 3d Real to Complex fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `pad0` is the padding along 0th dimension of Array
+/// - `pad1` is the padding along 1st dimension of Array
+/// - `pad2` is the padding along 2nd dimension of Array
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft3_r2c<T>(
+    input: &Array<T>,
+    norm_factor: f64,
+    pad0: i64,
+    pad1: i64,
+    pad2: i64,
+) -> Array<Complex<T>>
+where
+    T: HasAfEnum + RealFloating,
+    Complex<T>: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft3_r2c(
+            &mut temp as *mut af_array,
+            input.get(),
+            norm_factor,
+            pad0,
+            pad1,
+            pad2,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// 1d Complex to Real fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `is_odd` signifies if the output should be even or odd size
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft_c2r<T>(input: &Array<T>, norm_factor: f64, is_odd: bool) -> Array<T::BaseType>
+where
+    T: HasAfEnum + ComplexFloating,
+    <T as HasAfEnum>::BaseType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// 2d Complex to Real fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `is_odd` signifies if the output should be even or odd size
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft2_c2r<T>(input: &Array<T>, norm_factor: f64, is_odd: bool) -> Array<T::BaseType>
+where
+    T: HasAfEnum + ComplexFloating,
+    <T as HasAfEnum>::BaseType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft2_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// 3d Complex to Real fast fourier transform
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `norm_factor` is the normalization factor to be applied before fft is applied
+/// - `is_odd` signifies if the output should be even or odd size
+///
+/// # Return Values
+///
+/// Complex Array
+pub fn fft3_c2r<T>(input: &Array<T>, norm_factor: f64, is_odd: bool) -> Array<T::BaseType>
+where
+    T: HasAfEnum + ComplexFloating,
+    <T as HasAfEnum>::BaseType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_fft3_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/sparse/mod.rs.html b/src/arrayfire/sparse/mod.rs.html new file mode 100644 index 000000000..fc445ebc6 --- /dev/null +++ b/src/arrayfire/sparse/mod.rs.html @@ -0,0 +1,753 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+
+use super::core::{
+    af_array, dim_t, AfError, Array, FloatingPoint, HasAfEnum, SparseFormat, HANDLE_ERROR,
+};
+
+use libc::{c_int, c_uint, c_void};
+
+extern "C" {
+    fn af_create_sparse_array(
+        out: *mut af_array,
+        nRows: dim_t,
+        nCols: dim_t,
+        vals: af_array,
+        rowIdx: af_array,
+        colIdx: af_array,
+        stype: c_uint,
+    ) -> c_int;
+
+    fn af_create_sparse_array_from_ptr(
+        out: *mut af_array,
+        nRows: dim_t,
+        nCols: dim_t,
+        nNZ: dim_t,
+        values: *const c_void,
+        rowIdx: *const c_int,
+        colIdx: *const c_int,
+        aftype: c_uint,
+        stype: c_uint,
+        src: c_uint,
+    ) -> c_int;
+
+    fn af_create_sparse_array_from_dense(
+        out: *mut af_array,
+        dense: af_array,
+        stype: c_uint,
+    ) -> c_int;
+
+    fn af_sparse_convert_to(out: *mut af_array, input: af_array, dstStrge: c_uint) -> c_int;
+
+    fn af_sparse_to_dense(out: *mut af_array, sparse: af_array) -> c_int;
+
+    fn af_sparse_get_info(
+        vals: *mut af_array,
+        rIdx: *mut af_array,
+        cIdx: *mut af_array,
+        stype: *mut c_uint,
+        input: af_array,
+    ) -> c_int;
+
+    fn af_sparse_get_values(out: *mut af_array, input: af_array) -> c_int;
+
+    fn af_sparse_get_row_idx(out: *mut af_array, input: af_array) -> c_int;
+
+    fn af_sparse_get_col_idx(out: *mut af_array, input: af_array) -> c_int;
+
+    fn af_sparse_get_nnz(out: *mut dim_t, input: af_array) -> c_int;
+
+    fn af_sparse_get_storage(out: *mut c_uint, input: af_array) -> c_int;
+}
+
+/// Create sprase matrix from arrays
+///
+/// This function converts [Array](./struct.Array.html) of `values` into sparse array
+/// of `format` sparse format using arrays `row_indices` and `col_indices`.
+///
+/// # Parameters
+///
+/// - `rows` is the number of rows in the dense matrix
+/// - `cols` is the number of columns in the dense matrix
+/// - `values` is the \ref af::array containing the non-zero elements
+///   `of the matrix
+/// - `row_indices` is the row indices for the sparse array
+/// - `col_indices` is the column indices for the sparse array
+/// - `format` is the storage format of the sparse array
+///
+/// # Return Values
+///
+/// Array with data in given sparse format
+///
+/// # Note
+///
+/// This function only uses references of the input arrays to create the
+/// sparse data structure and does not perform deep copies.
+pub fn sparse<T>(
+    rows: u64,
+    cols: u64,
+    values: &Array<T>,
+    row_indices: &Array<i32>,
+    col_indices: &Array<i32>,
+    format: SparseFormat,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_create_sparse_array(
+            &mut temp as *mut af_array,
+            rows as dim_t,
+            cols as dim_t,
+            values.get(),
+            row_indices.get(),
+            col_indices.get(),
+            format as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Create sprase matrix from data on host memory
+///
+/// This function converts host array `values` into sparse array of `format` sparse
+/// format using host arrays `row_indices` and `col_indices`.
+///
+/// # Parameters
+///
+/// - `rows` is the number of rows in the dense matrix
+/// - `cols` is the number of columns in the dense matrix
+/// - `nzz` is the number of non zero elements in the dense matrix
+/// - `values` is the \ref af::array containing the non-zero elements
+///   `of the matrix
+/// - `row_indices` is the row indices for the sparse array
+/// - `col_indices` is the column indices for the sparse array
+/// - `format` is the storage format of the sparse array
+///
+/// # Return Values
+///
+/// Array with data in given sparse format
+///
+/// # Note
+///
+/// The rules for deep copy/shallow copy/reference are the same as for creating a
+/// regular [Array](./struct.Array.html).
+pub fn sparse_from_host<T>(
+    rows: u64,
+    cols: u64,
+    nzz: u64,
+    values: &[T],
+    row_indices: &[i32],
+    col_indices: &[i32],
+    format: SparseFormat,
+) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    let aftype = T::get_af_dtype();
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_create_sparse_array_from_ptr(
+            &mut temp as *mut af_array,
+            rows as dim_t,
+            cols as dim_t,
+            nzz as dim_t,
+            values.as_ptr() as *const c_void,
+            row_indices.as_ptr() as *const c_int,
+            col_indices.as_ptr() as *const c_int,
+            aftype as c_uint,
+            format as c_uint,
+            1,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Convert dense array to sparse array
+///
+/// # Parameters
+///
+/// - `dense` is the dense format array
+/// - `format` is the target sparse format
+///
+/// # Return Values
+///
+/// Sparse Array
+pub fn sparse_from_dense<T>(dense: &Array<T>, format: SparseFormat) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_create_sparse_array_from_dense(
+            &mut temp as *mut af_array,
+            dense.get(),
+            format as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Convert between sparse formats
+///
+/// # Parameters
+///
+/// - `input` is the input sparse array
+/// - `format` is the target sparse format
+///
+/// # Return Values
+///
+/// Sparse Array in targe sparse format.
+pub fn sparse_convert_to<T>(input: &Array<T>, format: SparseFormat) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val =
+            af_sparse_convert_to(&mut temp as *mut af_array, input.get(), format as c_uint);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Convert sparse array to dense array
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Dense Array
+pub fn sparse_to_dense<T>(input: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_sparse_to_dense(&mut temp as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Get sparse Array information
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// A tuple of values, row indices, column indices Arrays and SparseFormat enum.
+pub fn sparse_get_info<T>(input: &Array<T>) -> (Array<T>, Array<i32>, Array<i32>, SparseFormat)
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut val: af_array = std::ptr::null_mut();
+        let mut row: af_array = std::ptr::null_mut();
+        let mut col: af_array = std::ptr::null_mut();
+        let mut stype: u32 = 0;
+        let err_val = af_sparse_get_info(
+            &mut val as *mut af_array,
+            &mut row as *mut af_array,
+            &mut col as *mut af_array,
+            &mut stype as *mut c_uint,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (
+            val.into(),
+            row.into(),
+            col.into(),
+            SparseFormat::from(stype),
+        )
+    }
+}
+
+/// Get values of sparse Array
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Sparse array values
+pub fn sparse_get_values<T>(input: &Array<T>) -> Array<T>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut val: af_array = std::ptr::null_mut();
+        let err_val = af_sparse_get_values(&mut val as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        val.into()
+    }
+}
+
+/// Get row indices Array
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Array with row indices values of sparse Array
+pub fn sparse_get_row_indices<T>(input: &Array<T>) -> Array<i32>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut val: af_array = std::ptr::null_mut();
+        let err_val = af_sparse_get_row_idx(&mut val as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        val.into()
+    }
+}
+
+/// Get cololumn indices Array
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Array with coloumn indices values of sparse Array
+pub fn sparse_get_col_indices<T>(input: &Array<T>) -> Array<i32>
+where
+    T: HasAfEnum + FloatingPoint,
+{
+    unsafe {
+        let mut val: af_array = std::ptr::null_mut();
+        let err_val = af_sparse_get_col_idx(&mut val as *mut af_array, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+        val.into()
+    }
+}
+
+/// Get number of non-zero elements in sparse array
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Number of non-zero elements of sparse Array
+pub fn sparse_get_nnz<T: HasAfEnum>(input: &Array<T>) -> i64 {
+    let mut count: i64 = 0;
+    unsafe {
+        let err_val = af_sparse_get_nnz(&mut count as *mut dim_t, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    count
+}
+
+/// Get sparse format
+///
+/// # Parameters
+///
+/// - `input` is the sparse array
+///
+/// # Return Values
+///
+/// Sparse array format
+pub fn sparse_get_format<T: HasAfEnum>(input: &Array<T>) -> SparseFormat {
+    let mut stype: u32 = 0;
+    unsafe {
+        let err_val = af_sparse_get_storage(&mut stype as *mut c_uint, input.get());
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    SparseFormat::from(stype)
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/statistics/mod.rs.html b/src/arrayfire/statistics/mod.rs.html new file mode 100644 index 000000000..5c2efeb14 --- /dev/null +++ b/src/arrayfire/statistics/mod.rs.html @@ -0,0 +1,1283 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+
+use super::core::{
+    af_array, dim_t, AfError, Array, CovarianceComputable, HasAfEnum, MedianComputable,
+    RealFloating, RealNumber, TopkFn, VarianceBias, HANDLE_ERROR,
+};
+
+use libc::{c_double, c_int, c_uint};
+
+extern "C" {
+    fn af_mean(out: *mut af_array, arr: af_array, dim: dim_t) -> c_int;
+    fn af_median(out: *mut af_array, arr: af_array, dim: dim_t) -> c_int;
+
+    fn af_mean_weighted(out: *mut af_array, arr: af_array, wts: af_array, dim: dim_t) -> c_int;
+    fn af_var_weighted(out: *mut af_array, arr: af_array, wts: af_array, dim: dim_t) -> c_int;
+
+    fn af_mean_all(real: *mut c_double, imag: *mut c_double, arr: af_array) -> c_int;
+    fn af_median_all(real: *mut c_double, imag: *mut c_double, arr: af_array) -> c_int;
+
+    fn af_mean_all_weighted(
+        real: *mut c_double,
+        imag: *mut c_double,
+        arr: af_array,
+        wts: af_array,
+    ) -> c_int;
+    fn af_var_all_weighted(
+        real: *mut c_double,
+        imag: *mut c_double,
+        arr: af_array,
+        wts: af_array,
+    ) -> c_int;
+
+    fn af_corrcoef(real: *mut c_double, imag: *mut c_double, X: af_array, Y: af_array) -> c_int;
+    fn af_topk(
+        vals: *mut af_array,
+        idxs: *mut af_array,
+        arr: af_array,
+        k: c_int,
+        dim: c_int,
+        order: c_uint,
+    ) -> c_int;
+
+    fn af_meanvar(
+        mean: *mut af_array,
+        var: *mut af_array,
+        input: af_array,
+        weights: af_array,
+        bias: c_uint,
+        dim: dim_t,
+    ) -> c_int;
+    fn af_var_v2(out: *mut af_array, arr: af_array, bias_kind: c_uint, dim: dim_t) -> c_int;
+    fn af_cov_v2(out: *mut af_array, X: af_array, Y: af_array, bias_kind: c_uint) -> c_int;
+    fn af_stdev_v2(out: *mut af_array, arr: af_array, bias_kind: c_uint, dim: dim_t) -> c_int;
+    fn af_var_all_v2(
+        real: *mut c_double,
+        imag: *mut c_double,
+        arr: af_array,
+        bias_kind: c_uint,
+    ) -> c_int;
+    fn af_stdev_all_v2(
+        real: *mut c_double,
+        imag: *mut c_double,
+        arr: af_array,
+        bias_kind: c_uint,
+    ) -> c_int;
+}
+
+/// Find the median along a given dimension
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `dim` is dimension along which median has to be found
+///
+///# Return Values
+///
+/// An Array whose size is equal to input except along the dimension which
+/// median needs to be found. Array size along `dim` will be reduced to one.
+pub fn median<T>(input: &Array<T>, dim: i64) -> Array<T>
+where
+    T: HasAfEnum + MedianComputable,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_median(&mut temp as *mut af_array, input.get(), dim);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+macro_rules! stat_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `input` is the input Array
+        /// - `dim` is dimension along which the current stat has to be computed
+        ///
+        ///# Return Values
+        ///
+        /// An Array whose size is equal to input except along the dimension which
+        /// the stat operation is performed. Array size along `dim` will be reduced to one.
+        pub fn $fn_name<T>(input: &Array<T>, dim: i64) -> Array<T::MeanOutType>
+        where
+            T: HasAfEnum,
+            T::MeanOutType: HasAfEnum,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_fn(&mut temp as *mut af_array, input.get(), dim);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+stat_func_def!("Mean along specified dimension", mean, af_mean);
+
+macro_rules! stat_wtd_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `input` is the input Array
+        /// - `weights` Array has the weights to be used during the stat computation
+        /// - `dim` is dimension along which the current stat has to be computed
+        ///
+        ///# Return Values
+        ///
+        /// An Array whose size is equal to input except along the dimension which
+        /// the stat operation is performed. Array size along `dim` will be reduced to one.
+        pub fn $fn_name<T, W>(
+            input: &Array<T>,
+            weights: &Array<W>,
+            dim: i64,
+        ) -> Array<T::MeanOutType>
+        where
+            T: HasAfEnum,
+            T::MeanOutType: HasAfEnum,
+            W: HasAfEnum + RealFloating,
+        {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_fn(&mut temp as *mut af_array,input.get(), weights.get(), dim);
+                HANDLE_ERROR(AfError::from(err_val));
+                temp.into()
+            }
+        }
+    };
+}
+
+stat_wtd_func_def!(
+    "Weighted mean along specified dimension",
+    mean_weighted,
+    af_mean_weighted
+);
+stat_wtd_func_def!(
+    "Weight variance along specified dimension",
+    var_weighted,
+    af_var_weighted
+);
+
+/// Compute Variance along a specific dimension
+///
+/// # Parameters
+///
+/// - `arr` is the input Array
+/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed
+/// - `dim` is the dimension along which the variance is extracted
+///
+/// # Return Values
+///
+/// Array with variance of input Array `arr` along dimension `dim`.
+///
+/// [1]: ./enum.VarianceBias.html
+pub fn var_v2<T>(arr: &Array<T>, bias_kind: VarianceBias, dim: i64) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum,
+    T::MeanOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_var_v2(
+            &mut temp as *mut af_array,
+            arr.get(),
+            bias_kind as c_uint,
+            dim,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Compute Variance along a specific dimension
+///
+/// # Parameters
+///
+/// - `arr` is the input Array
+/// - `isbiased` is boolean denoting population variance(False) or Sample variance(True)
+/// - `dim` is the dimension along which the variance is extracted
+///
+/// # Return Values
+///
+/// Array with variance of input Array `arr` along dimension `dim`.
+#[deprecated(since = "3.8.0", note = "Please use var_v2 API")]
+pub fn var<T>(arr: &Array<T>, isbiased: bool, dim: i64) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum,
+    T::MeanOutType: HasAfEnum,
+{
+    var_v2(
+        arr,
+        if isbiased {
+            VarianceBias::SAMPLE
+        } else {
+            VarianceBias::POPULATION
+        },
+        dim,
+    )
+}
+
+/// Compute covariance of two Arrays
+///
+/// # Parameters
+///
+/// - `x` is the first Array
+/// - `y` is the second Array
+/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed
+///
+/// # Return Values
+///
+/// An Array with Covariance values
+///
+/// [1]: ./enum.VarianceBias.html
+pub fn cov_v2<T>(x: &Array<T>, y: &Array<T>, bias_kind: VarianceBias) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum + CovarianceComputable,
+    T::MeanOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_cov_v2(
+            &mut temp as *mut af_array,
+            x.get(),
+            y.get(),
+            bias_kind as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Compute covariance of two Arrays
+///
+/// # Parameters
+///
+/// - `x` is the first Array
+/// - `y` is the second Array
+/// - `isbiased` is boolean denoting if biased estimate should be taken(default: False)
+///
+/// # Return Values
+///
+/// An Array with Covariance values
+#[deprecated(since = "3.8.0", note = "Please use cov_v2 API")]
+pub fn cov<T>(x: &Array<T>, y: &Array<T>, isbiased: bool) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum + CovarianceComputable,
+    T::MeanOutType: HasAfEnum,
+{
+    cov_v2(
+        x,
+        y,
+        if isbiased {
+            VarianceBias::SAMPLE
+        } else {
+            VarianceBias::POPULATION
+        },
+    )
+}
+
+/// Compute Variance of all elements
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed
+///
+/// # Return Values
+///
+/// A tuple of 64-bit floating point values that has the variance of `input` Array.
+///
+/// [1]: ./enum.VarianceBias.html
+pub fn var_all_v2<T: HasAfEnum>(input: &Array<T>, bias_kind: VarianceBias) -> (f64, f64) {
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_var_all_v2(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+            bias_kind as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (real, imag)
+}
+
+/// Compute Variance of all elements
+///
+/// # Parameters
+///
+/// - `input` is the input Array
+/// - `isbiased` is boolean denoting population variance(False) or sample variance(True)
+///
+/// # Return Values
+///
+/// A tuple of 64-bit floating point values that has the variance of `input` Array.
+#[deprecated(since = "3.8.0", note = "Please use var_all_v2 API")]
+pub fn var_all<T: HasAfEnum>(input: &Array<T>, isbiased: bool) -> (f64, f64) {
+    var_all_v2(
+        input,
+        if isbiased {
+            VarianceBias::SAMPLE
+        } else {
+            VarianceBias::POPULATION
+        },
+    )
+}
+
+macro_rules! stat_all_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `input` is the input Array
+        ///
+        ///# Return Values
+        ///
+        /// A tuple of 64-bit floating point values with the stat values.
+        pub fn $fn_name<T: HasAfEnum>(input: &Array<T>) -> (f64, f64) {
+            let mut real: f64 = 0.0;
+            let mut imag: f64 = 0.0;
+            unsafe {
+                let err_val = $ffi_fn(
+                    &mut real as *mut c_double,
+                    &mut imag as *mut c_double,
+                    input.get(),
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            (real, imag)
+        }
+    };
+}
+
+stat_all_func_def!("Compute mean of all data", mean_all, af_mean_all);
+
+/// Compute median of all data
+///
+///# Parameters
+///
+/// - `input` is the input Array
+///
+///# Return Values
+///
+/// A tuple of 64-bit floating point values with the median
+pub fn median_all<T>(input: &Array<T>) -> (f64, f64)
+where
+    T: HasAfEnum + MedianComputable,
+{
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_median_all(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (real, imag)
+}
+
+macro_rules! stat_wtd_all_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => {
+        #[doc=$doc_str]
+        ///
+        ///# Parameters
+        ///
+        /// - `input` is the input Array
+        /// - `weights` Array has the weights
+        ///
+        ///# Return Values
+        ///
+        /// A tuple of 64-bit floating point values with the stat values.
+        pub fn $fn_name<T, W>(input: &Array<T>, weights: &Array<W>) -> (f64, f64)
+        where
+            T: HasAfEnum,
+            W: HasAfEnum + RealFloating,
+        {
+            let mut real: f64 = 0.0;
+            let mut imag: f64 = 0.0;
+            unsafe {
+                let err_val = $ffi_fn(
+                    &mut real as *mut c_double,
+                    &mut imag as *mut c_double,
+                    input.get(),
+                    weights.get(),
+                );
+                HANDLE_ERROR(AfError::from(err_val));
+            }
+            (real, imag)
+        }
+    };
+}
+
+stat_wtd_all_func_def!(
+    "Compute weighted mean of all data",
+    mean_all_weighted,
+    af_mean_all_weighted
+);
+stat_wtd_all_func_def!(
+    "Compute weighted variance of all data",
+    var_all_weighted,
+    af_var_all_weighted
+);
+
+/// Compute correlation coefficient
+///
+/// # Parameters
+///
+/// - `x` is the first Array
+/// - `y` isthe second Array
+///
+/// # Return Values
+/// A tuple of 64-bit floating point values with the coefficients.
+pub fn corrcoef<T>(x: &Array<T>, y: &Array<T>) -> (f64, f64)
+where
+    T: HasAfEnum + RealNumber,
+{
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_corrcoef(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            x.get(),
+            y.get(),
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (real, imag)
+}
+
+/// Find top k elements along a given dimension
+///
+/// This function returns the top k values along a given dimension of the input
+/// array. The indices along with their values are returned.
+///
+/// If the input is a multi-dimensional array, the indices will be the index of
+/// the value in that dimension. Order of duplicate values are not preserved.
+///
+/// This function is optimized for small values of k. Currently, topk elements
+/// can be found only along dimension 0.
+///
+/// # Parameters
+///
+/// - `input` is the values from which top k elements are to be retrieved
+/// - `k` is the number of top elements to be retrieve
+/// - `dim` is the dimension along which the retrieval operation has to performed
+/// - `order` is an enum that can take values of type [TopkFn](./enum.TopkFn.html)
+///
+/// # Return Values
+///
+/// A tuple(couple) of Array's with the first Array containing the topk values
+/// with the second Array containing the indices of the topk values in the input
+/// data.
+pub fn topk<T>(input: &Array<T>, k: u32, dim: i32, order: TopkFn) -> (Array<T>, Array<u32>)
+where
+    T: HasAfEnum,
+{
+    unsafe {
+        let mut t0: af_array = std::ptr::null_mut();
+        let mut t1: af_array = std::ptr::null_mut();
+        let err_val = af_topk(
+            &mut t0 as *mut af_array,
+            &mut t1 as *mut af_array,
+            input.get(),
+            k as c_int,
+            dim as c_int,
+            order as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (t0.into(), t1.into())
+    }
+}
+
+/// Calculate mean and variance in single API call
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `weights` Array has the weights to be used during the stat computation
+/// - `bias` is type of bias used for variance calculation
+/// - `dim` is dimension along which the current stat has to be computed
+///
+///# Return Values
+///
+/// A tuple of Arrays, whose size is equal to input except along the dimension which
+/// the stat operation is performed. Array size along `dim` will be reduced to one.
+///
+/// - First Array contains mean values
+/// - Second Array contains variance values
+pub fn meanvar<T, W>(
+    input: &Array<T>,
+    weights: &Array<W>,
+    bias: VarianceBias,
+    dim: i64,
+) -> (Array<T::MeanOutType>, Array<T::MeanOutType>)
+where
+    T: HasAfEnum,
+    T::MeanOutType: HasAfEnum,
+    W: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut mean: af_array = std::ptr::null_mut();
+        let mut var: af_array = std::ptr::null_mut();
+        let err_val = af_meanvar(
+            &mut mean as *mut af_array,
+            &mut var as *mut af_array,
+            input.get(),
+            weights.get(),
+            bias as c_uint,
+            dim,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (mean.into(), var.into())
+    }
+}
+
+/// Standard deviation along given axis
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed
+/// - `dim` is dimension along which the current stat has to be computed
+///
+///# Return Values
+///
+/// An Array whose size is equal to input except along the dimension which
+/// the stat operation is performed. Array size along `dim` will be reduced to one.
+///
+/// [1]: ./enum.VarianceBias.html
+pub fn stdev_v2<T>(input: &Array<T>, bias_kind: VarianceBias, dim: i64) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum,
+    T::MeanOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_stdev_v2(
+            &mut temp as *mut af_array,
+            input.get(),
+            bias_kind as c_uint,
+            dim,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Standard deviation along specified axis
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `dim` is dimension along which the current stat has to be computed
+///
+///# Return Values
+///
+/// An Array whose size is equal to input except along the dimension which
+/// the stat operation is performed. Array size along `dim` will be reduced to one.
+#[deprecated(since = "3.8.0", note = "Please use stdev_v2 API")]
+pub fn stdev<T>(input: &Array<T>, dim: i64) -> Array<T::MeanOutType>
+where
+    T: HasAfEnum,
+    T::MeanOutType: HasAfEnum,
+{
+    stdev_v2(input, VarianceBias::POPULATION, dim)
+}
+
+/// Compute standard deviation of all data
+///
+///# Parameters
+///
+/// - `input` is the input Array
+/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed
+///
+///# Return Values
+///
+/// A tuple of 64-bit floating point values with the stat values.
+///
+/// [1]: ./enum.VarianceBias.html
+pub fn stdev_all_v2<T: HasAfEnum>(input: &Array<T>, bias_kind: VarianceBias) -> (f64, f64) {
+    let mut real: f64 = 0.0;
+    let mut imag: f64 = 0.0;
+    unsafe {
+        let err_val = af_stdev_all_v2(
+            &mut real as *mut c_double,
+            &mut imag as *mut c_double,
+            input.get(),
+            bias_kind as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+    }
+    (real, imag)
+}
+
+/// Compute standard deviation of all data
+///
+///# Parameters
+///
+/// - `input` is the input Array
+///
+///# Return Values
+///
+/// A tuple of 64-bit floating point values with the stat values.
+pub fn stdev_all<T: HasAfEnum>(input: &Array<T>) -> (f64, f64) {
+    stdev_all_v2(input, VarianceBias::POPULATION)
+}
+
+
\ No newline at end of file diff --git a/src/arrayfire/vision/mod.rs.html b/src/arrayfire/vision/mod.rs.html new file mode 100644 index 000000000..095d06a21 --- /dev/null +++ b/src/arrayfire/vision/mod.rs.html @@ -0,0 +1,1371 @@ +mod.rs - source + + + +
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+
+use super::core::{
+    af_array, af_features, dim_t, AfError, Array, HasAfEnum, HomographyType, ImageFilterType,
+    MatchType, RealFloating, HANDLE_ERROR,
+};
+
+use libc::{c_float, c_int, c_uint};
+use std::mem;
+
+// af_sift and af_gloh uses patented algorithms, so didn't add them
+// they are NOT built using installer builds
+
+extern "C" {
+    fn af_create_features(feat: *mut af_features, num: dim_t) -> c_int;
+    fn af_retain_features(feat: *mut af_features, feat: af_features) -> c_int;
+    fn af_get_features_num(num: *mut dim_t, feat: af_features) -> c_int;
+    fn af_get_features_xpos(out: *mut af_array, feat: af_features) -> c_int;
+    fn af_get_features_ypos(out: *mut af_array, feat: af_features) -> c_int;
+    fn af_get_features_score(out: *mut af_array, feat: af_features) -> c_int;
+    fn af_get_features_orientation(out: *mut af_array, feat: af_features) -> c_int;
+    fn af_get_features_size(out: *mut af_array, feat: af_features) -> c_int;
+    fn af_release_features(feat: af_features) -> c_int;
+
+    fn af_fast(
+        out: *mut af_features,
+        input: af_array,
+        thr: c_float,
+        arc_len: c_uint,
+        non_max: bool,
+        feature_ratio: c_float,
+        edge: c_uint,
+    ) -> c_int;
+
+    fn af_harris(
+        out: *mut af_features,
+        input: af_array,
+        m: c_uint,
+        r: c_float,
+        s: c_float,
+        bs: c_uint,
+        k: c_float,
+    ) -> c_int;
+
+    fn af_orb(
+        out: *mut af_features,
+        desc: *mut af_array,
+        arr: af_array,
+        fast_thr: c_float,
+        max_feat: c_uint,
+        scl_fctr: c_float,
+        levels: c_uint,
+        blur_img: bool,
+    ) -> c_int;
+
+    fn af_hamming_matcher(
+        idx: *mut af_array,
+        dist: *mut af_array,
+        query: af_array,
+        train: af_array,
+        dist_dim: dim_t,
+        n_dist: c_uint,
+    ) -> c_int;
+
+    fn af_nearest_neighbour(
+        idx: *mut af_array,
+        dist: *mut af_array,
+        q: af_array,
+        t: af_array,
+        dist_dim: dim_t,
+        n_dist: c_uint,
+        dist_type: c_int,
+    ) -> c_int;
+
+    fn af_match_template(
+        out: *mut af_array,
+        search_img: af_array,
+        template_img: af_array,
+        mtype: c_uint,
+    ) -> c_int;
+
+    fn af_susan(
+        feat: *mut af_features,
+        i: af_array,
+        r: c_uint,
+        d: c_float,
+        g: c_float,
+        f: c_float,
+        e: c_uint,
+    ) -> c_int;
+
+    fn af_dog(out: *mut af_array, i: af_array, r1: c_int, r2: c_int) -> c_int;
+
+    fn af_homography(
+        H: *mut af_array,
+        inliers: *mut c_int,
+        x_src: af_array,
+        y_src: af_array,
+        x_dst: af_array,
+        y_dst: af_array,
+        htype: c_uint,
+        inlier_thr: c_float,
+        iterations: c_uint,
+        otype: c_uint,
+    ) -> c_int;
+}
+
+/// A set of Array objects (usually, used in Computer vision context)
+///
+/// `Features` struct is used by computer vision functions
+/// to return the outcome of their operation. Typically, such output
+/// has the following Arrays:
+///
+/// - X positions of the features
+/// - Y positions of the features
+/// - Scores of the features
+/// - Orientations of the features
+/// - Sizes of the features
+///
+/// ## Sharing Across Threads
+///
+/// While sharing this object with other threads, there is no need to wrap
+/// this in an Arc object unless only one such object is required to exist.
+/// The reason being that ArrayFire's internal details that are pointed to
+/// by the features handle are appropriately reference counted in thread safe
+/// manner. However, if these features are to be edited, then please do wrap
+/// the object using a Mutex or Read-Write lock.
+pub struct Features {
+    feat: af_features,
+}
+
+unsafe impl Send for Features {}
+unsafe impl Sync for Features {}
+
+macro_rules! feat_func_def {
+    ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => (
+        #[doc=$doc_str]
+        pub fn $fn_name(&self) -> Array<f32> {
+            unsafe {
+                let mut temp: af_array = std::ptr::null_mut();
+                let err_val = $ffi_name(&mut temp as *mut af_array, self.feat);
+                HANDLE_ERROR(AfError::from(err_val));
+
+                let temp_array: Array<f32> = temp.into();
+                let retained = temp_array.clone();
+                mem::forget(temp_array);
+
+                retained
+            }
+        }
+    )
+}
+
+impl Features {
+    /// Create and return an object of type Features
+    ///
+    /// This object is basically a bunch of Arrays.
+    pub fn new(n: u64) -> Self {
+        unsafe {
+            let mut temp: af_features = std::ptr::null_mut();
+            let err_val = af_create_features(&mut temp as *mut af_features, n as dim_t);
+            HANDLE_ERROR(AfError::from(err_val));
+            Self { feat: temp }
+        }
+    }
+
+    /// Get total number of features found
+    pub fn num_features(&self) -> i64 {
+        let mut temp: i64 = 0;
+        unsafe {
+            let err_val = af_get_features_num(
+                &mut temp as *mut dim_t,
+                self.feat as *const dim_t as af_features,
+            );
+            HANDLE_ERROR(AfError::from(err_val));
+        }
+        temp
+    }
+
+    feat_func_def!("Get x coordinates Array", xpos, af_get_features_xpos);
+    feat_func_def!("Get y coordinates Array", ypos, af_get_features_ypos);
+    feat_func_def!("Get score Array", score, af_get_features_score);
+    feat_func_def!(
+        "Get orientation Array",
+        orientation,
+        af_get_features_orientation
+    );
+    feat_func_def!("Get features size Array", size, af_get_features_size);
+
+    /// Get the internal handle for [Features](./struct.Features.html) object
+    pub unsafe fn get(&self) -> af_features {
+        self.feat
+    }
+}
+
+impl Clone for Features {
+    fn clone(&self) -> Self {
+        unsafe {
+            let mut temp: af_features = std::ptr::null_mut();
+            let ret_val = af_retain_features(&mut temp as *mut af_features, self.feat);
+            HANDLE_ERROR(AfError::from(ret_val));
+            Self { feat: temp }
+        }
+    }
+}
+
+impl Drop for Features {
+    fn drop(&mut self) {
+        unsafe {
+            let ret_val = af_release_features(self.feat);
+            HANDLE_ERROR(AfError::from(ret_val));
+        }
+    }
+}
+
+/// Fast feature detector
+///
+/// A circle of radius 3 pixels, translating into a total of 16 pixels, is checked for sequential
+/// segments of pixels much brighter or much darker than the central one. For a pixel p to be
+/// considered a feature, there must exist a sequential segment of arc_length pixels in the circle
+/// around it such that all are greather than (p + thr) or smaller than (p - thr). After all
+/// features in the image are detected, if nonmax is true, the non-maximal suppression is applied,
+/// checking all detected features and the features detected in its 8-neighborhood and discard it
+/// if its score is non maximal.
+///
+/// # Parameters
+///
+/// - `input` - the input image Array
+/// - `thr` - FAST threshold for which pixel of the circle around the center pixel is considered to
+/// be greater or smaller
+/// - `arc_len` - length of arc (or sequential segment) to be tested, must be within range [9-16]
+/// - `non_max` - performs non-maximal supression if true
+/// - `feat_ratio` - maximum ratio of features to detect, the maximum number of features is
+/// calculated by `feature_ratio * num of elements`. The maximum number of features is not based on
+/// the score, instead, features detected after the limit is reached are discarded.
+/// - `edge` - is the length of the edges in the image to be discarded by FAST(minimum is 3, as the
+/// radius of the circle)
+///
+/// # Return Values
+///
+/// This function returns an object of struct [Features](./struct.Features.html) containing Arrays
+/// for x and y coordinates and score, while array oreientation is set to 0 as FAST does not
+/// compute orientation. Size is set to 1 as FAST does not compute multiple scales.
+pub fn fast<T>(
+    input: &Array<T>,
+    thr: f32,
+    arc_len: u32,
+    non_max: bool,
+    feat_ratio: f32,
+    edge: u32,
+) -> Features
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_features = std::ptr::null_mut();
+        let err_val = af_fast(
+            &mut temp as *mut af_features,
+            input.get(),
+            thr,
+            arc_len,
+            non_max,
+            feat_ratio,
+            edge,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        Features { feat: temp }
+    }
+}
+
+/// Harris corner detector.
+///
+/// Compute corners using the Harris corner detector approach. For each pixel, a small window is
+/// used to calculate the determinant and trace of such a window, from which a response is
+/// calculated. Pixels are considered corners if they are local maximas and have a high positive
+/// response.
+///
+/// # Parameters
+///
+/// - `input` is the array containing a grayscale image (color images are not supported)
+/// - `max_corners` is the maximum number of corners to keep, only retains those with highest Harris responses
+/// - `min_response` is the minimum response in order for a corner to be retained, only used if max_corners = 0
+/// - `sigma` is the standard deviation of a circular window (its dimensions will be calculated according to the standard deviation), the covariation matrix will be calculated to a circular neighborhood of this standard deviation (only used when block_size == 0, must be >= 0.5f and <= 5.0f)
+/// - `block_size` is square window size, the covariation matrix will be calculated to a square neighborhood of this size (must be >= 3 and <= 31)
+/// - `k_thr` is the Harris constant, usually set empirically to 0.04f (must be >= 0.01f)
+///
+/// # Return Values
+///
+/// This function returns an object of struct [Features](./struct.Features.html) containing Arrays
+/// for x and y coordinates and score, while array oreientation & size are set to 0 & 1,
+/// respectively, since harris doesn't compute that information
+pub fn harris<T>(
+    input: &Array<T>,
+    max_corners: u32,
+    min_response: f32,
+    sigma: f32,
+    block_size: u32,
+    k_thr: f32,
+) -> Features
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut temp: af_features = std::ptr::null_mut();
+        let err_val = af_harris(
+            &mut temp as *mut af_features,
+            input.get(),
+            max_corners,
+            min_response,
+            sigma,
+            block_size,
+            k_thr,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        Features { feat: temp }
+    }
+}
+
+/// ORB feature descriptor
+///
+/// Extract ORB descriptors from FAST features that hold higher Harris responses. FAST does not
+/// compute orientation, thus, orientation of features is calculated using the intensity centroid.
+/// As FAST is also not multi-scale enabled, a multi-scale pyramid is calculated by downsampling
+/// the input image multiple times followed by FAST feature detection on each scale.
+///
+/// # Parameters
+///
+/// - `input` - the input image Array
+/// - `fast_thr` - FAST threshold for which a pixel of the circle around the central pixel is
+/// considered to be brighter or darker
+/// - `max_feat` - maximum number of features to hold
+/// - `scl_fctr` - factor to downsample the input image, meaning that each level with hold prior
+/// level dimensions divided by `scl_fctr`
+/// - `levels` - number of levels to be computed for the image pyramid
+/// - `blur_img` - blur image with a Gaussian filter with sigma=2 before computing descriptors to
+/// increase robustness against noise if true
+///
+/// # Return Values
+///
+/// This function returns a tuple of [`Features`](./struct.Features.html) and [`Array`](./struct.Array.html). The features objects composed of Arrays for x and y coordinates, score, orientation and size of selected features. The Array object is a two dimensional Array of size Nx8 where N is number of selected features.
+pub fn orb<T>(
+    input: &Array<T>,
+    fast_thr: f32,
+    max_feat: u32,
+    scl_fctr: f32,
+    levels: u32,
+    blur_img: bool,
+) -> (Features, Array<T>)
+where
+    T: HasAfEnum + RealFloating,
+{
+    unsafe {
+        let mut f: af_features = std::ptr::null_mut();
+        let mut d: af_array = std::ptr::null_mut();
+        let err_val = af_orb(
+            &mut f as *mut af_features,
+            &mut d as *mut af_array,
+            input.get(),
+            fast_thr,
+            max_feat,
+            scl_fctr,
+            levels,
+            blur_img,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (Features { feat: f }, d.into())
+    }
+}
+
+/// Hamming feature matcher
+///
+/// Calculates Hamming distances between two 2-dimensional arrays containing features, one of the
+/// arrays containing the training data and the other the query data. One of the dimensions of the
+/// both arrays must be equal among them, identifying the length of each feature. The other
+/// dimension indicates the total number of features in each of the training and query arrays. Two
+/// 1-dimensional arrays are created as results, one containg the smallest N distances of the query
+/// array and another containing the indices of these distances in the training array. The
+/// resulting 1-dimensional arrays have length equal to the number of features contained in the
+/// query array.
+///
+/// # Parameters
+///
+/// - `query` - Array containing the data to be queried
+/// - `train` - Array containing the data to be used as training data
+/// - `dist_dims` - indicates the dimension to analyze for distance (the dimension indicated here
+/// must be of equal length for both query and train arrays)
+/// - `n_dist` - is the number of smallest distances to return (currently, only values <= 256 are supported)
+///
+///
+/// # Return Values
+///
+/// This function returns a tuple of [Array](./struct.Array.html)'s.
+///
+/// First Array is an array of MxN size, where M is equal to the number of query features and N is
+/// equal to n_dist. The value at position IxJ indicates the index of the Jth smallest distance to
+/// the Ith query value in the train data array. the index of the Ith smallest distance of the Mth
+/// query.
+///
+/// Second Array is an array of MxN size, where M is equal to the number of query features and N is
+/// equal to n_dist. The value at position IxJ indicates the Hamming distance of the Jth smallest
+/// distance to the Ith query value in the train data array.
+pub fn hamming_matcher<T>(
+    query: &Array<T>,
+    train: &Array<T>,
+    dist_dims: i64,
+    n_dist: u32,
+) -> (Array<u32>, Array<T::AggregateOutType>)
+where
+    T: HasAfEnum + ImageFilterType,
+    T::AggregateOutType: HasAfEnum,
+{
+    unsafe {
+        let mut idx: af_array = std::ptr::null_mut();
+        let mut dist: af_array = std::ptr::null_mut();
+        let err_val = af_hamming_matcher(
+            &mut idx as *mut af_array,
+            &mut dist as *mut af_array,
+            query.get(),
+            train.get(),
+            dist_dims,
+            n_dist,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (idx.into(), dist.into())
+    }
+}
+
+/// Nearest Neighbour.
+///
+/// Calculates nearest distances between two 2-dimensional arrays containing features based on the
+/// type of distance computation chosen. Currently, AF_SAD (sum of absolute differences), AF_SSD
+/// (sum of squared differences) and AF_SHD (hamming distance) are supported. One of the arrays
+/// containing the training data and the other the query data. One of the dimensions of the both
+/// arrays must be equal among them, identifying the length of each feature. The other dimension
+/// indicates the total number of features in each of the training and query arrays. Two
+/// 1-dimensional arrays are created as results, one containg the smallest N distances of the query
+/// array and another containing the indices of these distances in the training array. The resulting
+/// 1-dimensional arrays have length equal to the number of features contained in the query array.
+///
+/// # Parameters
+///
+/// - `query` is the array containing the data to be queried
+/// - `train` is the array containing the data used as training data
+/// - `dist_dim` indicates the dimension to analyze for distance (the dimension indicated here must be of equal length for both query and train arrays)
+/// - `n_dist` is the number of smallest distances to return (currently, only values <= 256 are supported)
+/// - `dist_type` is the distance computation type. Currently [`MatchType::SAD`](./enum.MatchType.html), [`MatchType::SSD`](./enum.MatchType.html), and [`MatchType::SHD`](./enum.MatchType.html) are supported.
+///
+/// # Return Values
+///
+/// A tuple of Arrays.
+///
+/// The first Array is is an array of MxN size, where M is equal to the number of query features
+/// and N is equal to `n_dist`. The value at position IxJ indicates the index of the Jth smallest
+/// distance to the Ith query value in the train data array. the index of the Ith smallest distance
+/// of the Mth query.
+///
+/// The second Array is is an array of MxN size, where M is equal to the number of query features
+/// and N is equal to `n_dist`. The value at position IxJ indicates the distance of the Jth smallest
+/// distance to the Ith query value in the train data array based on the `dist_type` chosen.
+pub fn nearest_neighbour<T>(
+    query: &Array<T>,
+    train: &Array<T>,
+    dist_dim: i64,
+    n_dist: u32,
+    dist_type: MatchType,
+) -> (Array<u32>, Array<T::AggregateOutType>)
+where
+    T: HasAfEnum + ImageFilterType,
+    T::AggregateOutType: HasAfEnum,
+{
+    unsafe {
+        let mut idx: af_array = std::ptr::null_mut();
+        let mut dist: af_array = std::ptr::null_mut();
+        let err_val = af_nearest_neighbour(
+            &mut idx as *mut af_array,
+            &mut dist as *mut af_array,
+            query.get(),
+            train.get(),
+            dist_dim,
+            n_dist,
+            dist_type as c_int,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (idx.into(), dist.into())
+    }
+}
+
+/// Image matching
+///
+/// Template matching is an image processing technique to find small patches of an image which
+/// match a given template image. A more in depth discussion on the topic can be found
+/// [here](https://en.wikipedia.org/wiki/Template_matching).
+///
+/// # Parameters
+///
+/// - `search_img` is an array with image data
+/// - `template_img` is the template we are looking for in the image
+/// - `mtype` is metric that should be used to calculate the disparity between window in the image and the template image. It can be one of the values defined by the enum [MatchType](./enum.MatchType.html).
+/// # Return Values
+///
+/// This function returns an Array with disparity values for the window starting at corresponding pixel position.
+pub fn match_template<T>(
+    search_img: &Array<T>,
+    template_img: &Array<T>,
+    mtype: MatchType,
+) -> Array<T::AbsOutType>
+where
+    T: HasAfEnum + ImageFilterType,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_match_template(
+            &mut temp as *mut af_array,
+            search_img.get(),
+            template_img.get(),
+            mtype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// SUSAN corner detector.
+///
+/// SUSAN is an acronym standing for Smallest Univalue Segment Assimilating Nucleus. This method
+/// places a circular disc over the pixel to be tested (a.k.a nucleus) to compute the corner
+/// measure of that corresponding pixel. The region covered by the circular disc is M, and a pixel
+/// in this region is represented by m⃗ ∈M where m⃗ 0 is the nucleus. Every pixel in the region is
+/// compared to the nucleus using the following comparison function:
+///
+/// c(m⃗ )=e^−((I(m⃗)−I(m⃗_0))/t)^6
+///
+/// where t is radius of the region, I is the brightness of the pixel.
+///
+/// Response of SUSAN operator is given by the following equation:
+///
+/// R(M) = g−n(M) if n(M) < g
+///
+/// R(M) = 0 otherwise,
+///
+/// where n(M)=∑c(m⃗) m⃗∈M, g is named the geometric threshold and n is the number of pixels in the
+/// mask which are within t of the nucleus.
+///
+/// Importance of the parameters, t and g is explained below:
+///
+/// - t determines how similar points have to be to the nucleusbefore they are considered to be a
+/// part of the univalue segment
+/// - g determines the minimum size of the univalue segment. For a large enough g, SUSAN operator
+/// becomes an edge dectector.
+///
+/// # Parameters
+///
+/// - `input` is input grayscale/intensity image
+/// - `radius` is the nucleus radius for each pixel neighborhood
+/// - `diff_thr` is intensity difference threshold a.k.a **t** from equations in description
+/// - `geom_thr` is the geometric threshold
+/// - `feature_ratio` is maximum number of features that will be returned by the function
+/// - `edge` indicates how many pixels width area should be skipped for corner detection
+///
+/// # Return Values
+/// An object of type [Features](./struct.Features.html) composed of arrays for x and y coordinates, score, orientation and size of selected features.
+pub fn susan<T>(
+    input: &Array<T>,
+    radius: u32,
+    diff_thr: f32,
+    geom_thr: f32,
+    feature_ratio: f32,
+    edge: u32,
+) -> Features
+where
+    T: HasAfEnum + ImageFilterType,
+{
+    unsafe {
+        let mut temp: af_features = std::ptr::null_mut();
+        let err_val = af_susan(
+            &mut temp as *mut af_features,
+            input.get(),
+            radius,
+            diff_thr,
+            geom_thr,
+            feature_ratio,
+            edge,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        Features { feat: temp }
+    }
+}
+
+/// Difference of Gaussians.
+///
+/// Given an image, this function computes two different versions of smoothed input image using the
+/// difference smoothing parameters and subtracts one from the other and returns the result.
+///
+/// # Parameters
+///
+/// - `input` is the input image
+/// - `radius1` is the radius of the first gaussian kernel
+/// - `radius2` is the radius of the second gaussian kernel
+///
+/// # Return Values
+///
+/// Difference of smoothed inputs - An Array.
+pub fn dog<T>(input: &Array<T>, radius1: i32, radius2: i32) -> Array<T::AbsOutType>
+where
+    T: HasAfEnum + ImageFilterType,
+    T::AbsOutType: HasAfEnum,
+{
+    unsafe {
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_dog(&mut temp as *mut af_array, input.get(), radius1, radius2);
+        HANDLE_ERROR(AfError::from(err_val));
+        temp.into()
+    }
+}
+
+/// Homography estimation
+///
+/// Homography estimation find a perspective transform between two sets of 2D points.
+/// Currently, two methods are supported for the estimation, RANSAC (RANdom SAmple Consensus)
+/// and LMedS (Least Median of Squares). Both methods work by randomly selecting a subset
+/// of 4 points of the set of source points, computing the eigenvectors of that set and
+/// finding the perspective transform. The process is repeated several times, a maximum of
+/// times given by the value passed to the iterations arguments for RANSAC (for the CPU
+/// backend, usually less than that, depending on the quality of the dataset, but for CUDA
+/// and OpenCL backends the transformation will be computed exactly the amount of times
+/// passed via the iterations parameter), the returned value is the one that matches the
+/// best number of inliers, which are all of the points that fall within a maximum L2
+/// distance from the value passed to the inlier_thr argument.
+///
+/// # Parameters
+///
+/// - `x_src` is the x coordinates of the source points.
+/// - `y_src` is the y coordinates of the source points.
+/// - `x_dst` is the x coordinates of the destination points.
+/// - `y_dst` is the y coordinates of the destination points.
+/// - `htype` can be AF_HOMOGRAPHY_RANSAC, for which a RANdom SAmple Consensus will be used to evaluate the homography quality (e.g., number of inliers), or AF_HOMOGRAPHY_LMEDS, which will use Least Median of Squares method to evaluate homography quality
+/// - `inlier_thr` - if htype is AF_HOMOGRAPHY_RANSAC, this parameter will five the maximum L2-distance for a point to be considered an inlier.
+/// - `iterations` is the maximum number of iterations when htype is AF_HOMOGRAPHY_RANSAC and backend is CPU,if backend is CUDA or OpenCL, iterations is the total number of iterations, an iteration is a selection of 4 random points for which the homography is estimated and evaluated for number of inliers.
+/// - `otype` is the array type for the homography output.
+///
+/// # Return Values
+///
+/// Returns a tuple of Array and int.
+///
+/// - `H` is a 3x3 array containing the estimated homography.
+/// - `inliers` is the number of inliers that the homography was estimated to comprise, in the case that htype is AF_HOMOGRAPHY_RANSAC, a higher inlier_thr value will increase the estimated inliers. Note that if the number of inliers is too low, it is likely that a bad homography will be returned.
+pub fn homography<OutType>(
+    x_src: &Array<f32>,
+    y_src: &Array<f32>,
+    x_dst: &Array<f32>,
+    y_dst: &Array<f32>,
+    htype: HomographyType,
+    inlier_thr: f32,
+    iterations: u32,
+) -> (Array<OutType>, i32)
+where
+    OutType: HasAfEnum + RealFloating,
+{
+    let otype = OutType::get_af_dtype();
+    unsafe {
+        let mut inliers: i32 = 0;
+        let mut temp: af_array = std::ptr::null_mut();
+        let err_val = af_homography(
+            &mut temp as *mut af_array,
+            &mut inliers as *mut c_int,
+            x_src.get(),
+            y_src.get(),
+            x_dst.get(),
+            y_dst.get(),
+            htype as c_uint,
+            inlier_thr,
+            iterations,
+            otype as c_uint,
+        );
+        HANDLE_ERROR(AfError::from(err_val));
+        (temp.into(), inliers)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/blas/mod.rs b/src/blas/mod.rs deleted file mode 100644 index 040858e46..000000000 --- a/src/blas/mod.rs +++ /dev/null @@ -1,256 +0,0 @@ -use super::core::{ - af_array, AfError, Array, CublasMathMode, FloatingPoint, HasAfEnum, MatProp, HANDLE_ERROR, -}; - -use libc::{c_int, c_uint, c_void}; -use std::vec::Vec; - -extern "C" { - fn af_gemm( - out: *mut af_array, - optlhs: c_uint, - optrhs: c_uint, - alpha: *const c_void, - lhs: af_array, - rhs: af_array, - beta: *const c_void, - ) -> c_int; - - fn af_matmul( - out: *mut af_array, - lhs: af_array, - rhs: af_array, - optlhs: c_uint, - optrhs: c_uint, - ) -> c_int; - - fn af_dot( - out: *mut af_array, - lhs: af_array, - rhs: af_array, - optlhs: c_uint, - optrhs: c_uint, - ) -> c_int; - - fn af_transpose(out: *mut af_array, arr: af_array, conjugate: bool) -> c_int; - fn af_transpose_inplace(arr: af_array, conjugate: bool) -> c_int; - - fn afcu_cublasSetMathMode(mode: c_int) -> c_int; -} - -/// BLAS general matrix multiply (GEMM) of two Array objects -/// -/// -/// This provides a general interface to the BLAS level 3 general matrix multiply (GEMM), -/// which is generally defined as: -/// -/// \begin{equation} -/// C = \alpha * opA(A)opB(B) + \beta * C -/// \end{equation} -/// -/// where $\alpha$ (**alpha**) and $\beta$ (**beta**) are both scalars; $A$ and $B$ are the matrix -/// multiply operands; and $opA$ and $opB$ are noop -/// (if optLhs is [MatProp::NONE](./enum.MatProp.html)) or transpose -/// (if optLhs is [MatProp::TRANS](./enum.MatProp.html)) operations on $A$ or $B$ before the -/// actual GEMM operation. Batched GEMM is supported if at least either $A$ or $B$ have more than -/// two dimensions (see [af::matmul](http://arrayfire.org/docs/group__blas__func__matmul.htm#ga63306b6ed967bd1055086db862fe885b) -/// for more details on broadcasting). However, only one **alpha** and one **beta** can be used -/// for all of the batched matrix operands. -/// -/// The `output` Array can be used both as an input and output. An allocation will be performed -/// if you pass an empty Array (i.e. `let c: Array = (0 as i64).into();`). If a valid Array -/// is passed as $C$, the operation will be performed on that Array itself. The C Array must be -/// the correct type and shape; otherwise, an error will be thrown. -/// -/// Note: Passing an Array that has not been initialized to the C array -/// will cause undefined behavior. -/// -/// # Examples -/// -/// Given below is an example of using gemm API with existing Arrays -/// -/// ```rust -/// use arrayfire::{Array, Dim4, print, randu, gemm}; -/// -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// -/// let alpha = vec![1.0 as f32]; -/// let beta = vec![2.0 as f32]; -/// -/// let lhs = randu::(dims); -/// let rhs = randu::(dims); -/// -/// let mut result = Array::new_empty(dims); -/// gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE, -/// alpha, &lhs, &rhs, beta); -/// ``` -/// -/// If you don't have an existing Array, you can also use gemm in the following fashion. -/// However, if there is no existing Array that you need to fill and your use case doesn't -/// deal with alpha and beta from gemm equation, it is recommended to use -/// [matmul](./fn.matmul.html) for more terse code. -/// -/// ```rust -/// use arrayfire::{Array, Dim4, af_array, print, randu, gemm}; -/// -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// -/// let alpha = vec![1.0 as f32]; -/// let beta = vec![2.0 as f32]; -/// -/// let lhs = randu::(dims); -/// let rhs = randu::(dims); -/// -/// let mut result: Array:: = (std::ptr::null_mut() as af_array).into(); -/// -/// gemm(&mut result, arrayfire::MatProp::NONE, arrayfire::MatProp::NONE, -/// alpha, &lhs, &rhs, beta); -/// ``` -/// -/// # Parameters -/// -/// - `optlhs` - Transpose left hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html) -/// - `optrhs` - Transpose right hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html) -/// - `alpha` is alpha value; -/// - `lhs` is the Array on left hand side -/// - `rhs` is the Array on right hand side -/// - `beta` is beta value; -/// -/// # Return Values -/// -/// Array, result of gemm operation -pub fn gemm( - output: &mut Array, - optlhs: MatProp, - optrhs: MatProp, - alpha: Vec, - lhs: &Array, - rhs: &Array, - beta: Vec, -) where - T: HasAfEnum + FloatingPoint, -{ - let mut out = unsafe { output.get() }; - let err_val = unsafe { - af_gemm( - &mut out as *mut af_array, - optlhs as c_uint, - optrhs as c_uint, - alpha.as_ptr() as *const c_void, - lhs.get(), - rhs.get(), - beta.as_ptr() as *const c_void, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - output.set(out); -} - -/// Matrix multiple of two Arrays -/// -/// # Parameters -/// -/// - `lhs` is the Array on left hand side -/// - `rhs` is the Array on right hand side -/// - `optlhs` - Transpose left hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html) -/// - `optrhs` - Transpose right hand side before the function is performed, uses one of the values of [MatProp](./enum.MatProp.html) -/// -/// # Return Values -/// -/// The result Array of matrix multiplication -pub fn matmul(lhs: &Array, rhs: &Array, optlhs: MatProp, optrhs: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_matmul( - &mut temp as *mut af_array, - lhs.get(), - rhs.get(), - optlhs as c_uint, - optrhs as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Calculate the dot product of vectors. -/// -/// Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors. -/// -/// # Parameters -/// -/// - `lhs` - Left hand side of dot operation -/// - `rhs` - Right hand side of dot operation -/// - `optlhs` - Options for lhs. Currently only NONE value from [MatProp](./enum.MatProp.html) is supported. -/// - `optrhs` - Options for rhs. Currently only NONE value from [MatProp](./enum.MatProp.html) is supported. -/// -/// # Return Values -/// -/// The result of dot product. -pub fn dot(lhs: &Array, rhs: &Array, optlhs: MatProp, optrhs: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_dot( - &mut temp as *mut af_array, - lhs.get(), - rhs.get(), - optlhs as c_uint, - optrhs as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Transpose of a matrix. -/// -/// # Parameters -/// -/// - `arr` is the input Array -/// - `conjugate` is a boolean that indicates if the transpose operation needs to be a conjugate -/// transpose -/// -/// # Return Values -/// -/// Transposed Array. -pub fn transpose(arr: &Array, conjugate: bool) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_transpose(&mut temp as *mut af_array, arr.get(), conjugate) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inplace transpose of a matrix. -/// -/// # Parameters -/// -/// - `arr` is the input Array that has to be transposed -/// - `conjugate` is a boolean that indicates if the transpose operation needs to be a conjugate -/// transpose -pub fn transpose_inplace(arr: &mut Array, conjugate: bool) { - let err_val = unsafe { af_transpose_inplace(arr.get(), conjugate) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Sets the cuBLAS math mode for the internal handle. -/// -/// See the cuBLAS documentation for additional details -/// -/// # Parameters -/// -/// - `mode` takes a value of [CublasMathMode](./enum.CublasMathMode.html) enum -pub fn set_cublas_mode(mode: CublasMathMode) { - unsafe { - afcu_cublasSetMathMode(mode as c_int); - //let err_val = afcu_cublasSetMathMode(mode as c_int); - // FIXME(wonder if this something to throw off, - // the program state is not invalid or anything - // HANDLE_ERROR(AfError::from(err_val)); - } -} diff --git a/src/core/arith.rs b/src/core/arith.rs deleted file mode 100644 index d0f1dda89..000000000 --- a/src/core/arith.rs +++ /dev/null @@ -1,984 +0,0 @@ -use super::array::Array; -use super::data::{constant, tile, ConstGenerator}; -use super::defines::AfError; -use super::dim4::Dim4; -use super::error::HANDLE_ERROR; -use super::util::{af_array, HasAfEnum, ImplicitPromote, IntegralType}; - -use half::f16; -use num::Zero; - -use libc::c_int; -use num::Complex; -use std::mem; -use std::ops::Neg; -use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub}; - -extern "C" { - fn af_add(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_sub(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_mul(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_div(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - - fn af_lt(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_gt(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_le(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_ge(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_eq(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_or(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - - fn af_neq(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_and(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_rem(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_mod(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - - fn af_bitand(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_bitor(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_bitxor(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_bitshiftl(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_bitshiftr(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_minof(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_maxof(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_clamp( - out: *mut af_array, - inp: af_array, - lo: af_array, - hi: af_array, - batch: bool, - ) -> c_int; - - fn af_not(out: *mut af_array, arr: af_array) -> c_int; - fn af_abs(out: *mut af_array, arr: af_array) -> c_int; - fn af_arg(out: *mut af_array, arr: af_array) -> c_int; - fn af_sign(out: *mut af_array, arr: af_array) -> c_int; - fn af_ceil(out: *mut af_array, arr: af_array) -> c_int; - fn af_round(out: *mut af_array, arr: af_array) -> c_int; - fn af_trunc(out: *mut af_array, arr: af_array) -> c_int; - fn af_floor(out: *mut af_array, arr: af_array) -> c_int; - - fn af_hypot(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - - fn af_sin(out: *mut af_array, arr: af_array) -> c_int; - fn af_cos(out: *mut af_array, arr: af_array) -> c_int; - fn af_tan(out: *mut af_array, arr: af_array) -> c_int; - fn af_asin(out: *mut af_array, arr: af_array) -> c_int; - fn af_acos(out: *mut af_array, arr: af_array) -> c_int; - fn af_atan(out: *mut af_array, arr: af_array) -> c_int; - - fn af_atan2(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_cplx2(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_root(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - fn af_pow(out: *mut af_array, lhs: af_array, rhs: af_array, batch: bool) -> c_int; - - fn af_cplx(out: *mut af_array, arr: af_array) -> c_int; - fn af_real(out: *mut af_array, arr: af_array) -> c_int; - fn af_imag(out: *mut af_array, arr: af_array) -> c_int; - fn af_conjg(out: *mut af_array, arr: af_array) -> c_int; - fn af_sinh(out: *mut af_array, arr: af_array) -> c_int; - fn af_cosh(out: *mut af_array, arr: af_array) -> c_int; - fn af_tanh(out: *mut af_array, arr: af_array) -> c_int; - fn af_asinh(out: *mut af_array, arr: af_array) -> c_int; - fn af_acosh(out: *mut af_array, arr: af_array) -> c_int; - fn af_atanh(out: *mut af_array, arr: af_array) -> c_int; - fn af_pow2(out: *mut af_array, arr: af_array) -> c_int; - fn af_exp(out: *mut af_array, arr: af_array) -> c_int; - fn af_sigmoid(out: *mut af_array, arr: af_array) -> c_int; - fn af_expm1(out: *mut af_array, arr: af_array) -> c_int; - fn af_erf(out: *mut af_array, arr: af_array) -> c_int; - fn af_erfc(out: *mut af_array, arr: af_array) -> c_int; - fn af_log(out: *mut af_array, arr: af_array) -> c_int; - fn af_log1p(out: *mut af_array, arr: af_array) -> c_int; - fn af_log10(out: *mut af_array, arr: af_array) -> c_int; - fn af_log2(out: *mut af_array, arr: af_array) -> c_int; - fn af_sqrt(out: *mut af_array, arr: af_array) -> c_int; - fn af_rsqrt(out: *mut af_array, arr: af_array) -> c_int; - fn af_cbrt(out: *mut af_array, arr: af_array) -> c_int; - fn af_factorial(out: *mut af_array, arr: af_array) -> c_int; - fn af_tgamma(out: *mut af_array, arr: af_array) -> c_int; - fn af_lgamma(out: *mut af_array, arr: af_array) -> c_int; - fn af_iszero(out: *mut af_array, arr: af_array) -> c_int; - fn af_isinf(out: *mut af_array, arr: af_array) -> c_int; - fn af_isnan(out: *mut af_array, arr: af_array) -> c_int; - fn af_bitnot(out: *mut af_array, arr: af_array) -> c_int; -} - -/// Enables use of `!` on objects of type [Array](./struct.Array.html) -impl<'f, T> Not for &'f Array -where - T: HasAfEnum, -{ - type Output = Array; - - fn not(self) -> Self::Output { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_not(&mut temp as *mut af_array, self.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -macro_rules! unary_func { - [$doc_str: expr, $fn_name: ident, $ffi_fn: ident, $out_type: ident] => ( - #[doc=$doc_str] - /// - /// This is an element wise unary operation. - pub fn $fn_name(input: &Array) -> Array< T::$out_type > - where T::$out_type: HasAfEnum { - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_fn(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - - } - ) -} - -unary_func!("Computes absolute value", abs, af_abs, AbsOutType); -unary_func!("Computes phase value", arg, af_arg, ArgOutType); - -unary_func!( - "Truncate the values in an Array", - trunc, - af_trunc, - AbsOutType -); -unary_func!( - "Computes the sign of input Array values", - sign, - af_sign, - AbsOutType -); -unary_func!("Round the values in an Array", round, af_round, AbsOutType); -unary_func!("Floor the values in an Array", floor, af_floor, AbsOutType); -unary_func!("Ceil the values in an Array", ceil, af_ceil, AbsOutType); - -unary_func!("Compute sigmoid function", sigmoid, af_sigmoid, AbsOutType); -unary_func!( - "Compute e raised to the power of value -1", - expm1, - af_expm1, - AbsOutType -); -unary_func!("Compute error function value", erf, af_erf, AbsOutType); -unary_func!( - "Compute the complementary error function value", - erfc, - af_erfc, - AbsOutType -); - -unary_func!("Compute logarithm base 10", log10, af_log10, AbsOutType); -unary_func!( - "Compute the logarithm of input Array + 1", - log1p, - af_log1p, - AbsOutType -); -unary_func!("Compute logarithm base 2", log2, af_log2, AbsOutType); - -unary_func!("Compute the cube root", cbrt, af_cbrt, AbsOutType); -unary_func!("Compute gamma function", tgamma, af_tgamma, AbsOutType); -unary_func!( - "Compute the logarithm of absolute values of gamma function", - lgamma, - af_lgamma, - AbsOutType -); - -unary_func!("Compute acosh", acosh, af_acosh, UnaryOutType); -unary_func!("Compute acos", acos, af_acos, UnaryOutType); -unary_func!("Compute asin", asin, af_asin, UnaryOutType); -unary_func!("Compute asinh", asinh, af_asinh, UnaryOutType); -unary_func!("Compute atan", atan, af_atan, UnaryOutType); -unary_func!("Compute atanh", atanh, af_atanh, UnaryOutType); -unary_func!("Compute cos", cos, af_cos, UnaryOutType); -unary_func!("Compute cosh", cosh, af_cosh, UnaryOutType); -unary_func!( - "Compute e raised to the power of value", - exp, - af_exp, - UnaryOutType -); -unary_func!("Compute the natural logarithm", log, af_log, UnaryOutType); -unary_func!("Compute sin", sin, af_sin, UnaryOutType); -unary_func!("Compute sinh", sinh, af_sinh, UnaryOutType); -unary_func!("Compute the square root", sqrt, af_sqrt, UnaryOutType); -unary_func!( - "Compute the reciprocal square root", - rsqrt, - af_rsqrt, - UnaryOutType -); -unary_func!("Compute tan", tan, af_tan, UnaryOutType); -unary_func!("Compute tanh", tanh, af_tanh, UnaryOutType); - -unary_func!( - "Extract real values from a complex Array", - real, - af_real, - AbsOutType -); -unary_func!( - "Extract imaginary values from a complex Array", - imag, - af_imag, - AbsOutType -); -unary_func!( - "Create a complex Array from real Array", - cplx, - af_cplx, - ComplexOutType -); -unary_func!( - "Compute the complex conjugate", - conjg, - af_conjg, - ComplexOutType -); -unary_func!( - "Compute two raised to the power of value", - pow2, - af_pow2, - UnaryOutType -); -unary_func!( - "Compute the factorial", - factorial, - af_factorial, - UnaryOutType -); - -macro_rules! unary_boolean_func { - [$doc_str: expr, $fn_name: ident, $ffi_fn: ident] => ( - #[doc=$doc_str] - /// - /// This is an element wise unary operation. - pub fn $fn_name(input: &Array) -> Array { - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_fn(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - - } - ) -} - -unary_boolean_func!("Check if values are zero", iszero, af_iszero); -unary_boolean_func!("Check if values are infinity", isinf, af_isinf); -unary_boolean_func!("Check if values are NaN", isnan, af_isnan); - -macro_rules! binary_func { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - /// - /// This is an element wise binary operation. - /// - /// # Important Notes - /// - /// - If shape/dimensions of `lhs` and `rhs` are same, the value of `batch` parameter - /// has no effect. - /// - /// - If shape/dimensions of `lhs` and `rhs` are different, the value of `batch` has - /// to be set to `true`. In this case, the shapes of `lhs` and `rhs` have to satisfy the - /// following criteria: - /// - Same number of elements in `lhs` and `rhs` along a given dimension/axis - /// - Only one element in `lhs` or `rhs` along a given dimension/axis - pub fn $fn_name(lhs: &Array, rhs: &Array, batch: bool) -> Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { $ffi_fn(&mut temp as *mut af_array, lhs.get(), rhs.get(), batch) }; - HANDLE_ERROR(AfError::from(err_val)); - Into::>::into(temp) - } - }; -} - -binary_func!( - "Elementwise AND(bit) operation of two Arrays", - bitand, - af_bitand -); -binary_func!( - "Elementwise OR(bit) operation of two Arrays", - bitor, - af_bitor -); -binary_func!( - "Elementwise XOR(bit) operation of two Arrays", - bitxor, - af_bitxor -); -binary_func!( - "Elementwise minimum operation of two Arrays", - minof, - af_minof -); -binary_func!( - "Elementwise maximum operation of two Arrays", - maxof, - af_maxof -); -binary_func!( - "Compute length of hypotenuse of two Arrays", - hypot, - af_hypot -); - -/// Type Trait to convert to an [Array](./struct.Array.html) -/// -/// Generic functions that overload the binary operations such as add, div, mul, rem, ge etc. are -/// bound by this trait to allow combinations of scalar values and Array objects as parameters -/// to those functions. -/// -/// Internally, Convertable trait is implemented by following types. -/// -/// - f32 -/// - f64 -/// - num::Complex\ -/// - num::Complex\ -/// - bool -/// - i32 -/// - u32 -/// - u8 -/// - i64 -/// - u64 -/// - i16 -/// - u16 -/// -pub trait Convertable { - /// This type alias always points to `Self` which is the - /// type of [Array](./struct.Array.html) returned by the - /// trait method [convert](./trait.Convertable.html#tymethod.convert). - type OutType: HasAfEnum; - - /// Get an Array of implementors type - fn convert(&self) -> Array; -} - -impl Convertable for T -where - T: Clone + ConstGenerator, -{ - type OutType = T; - - fn convert(&self) -> Array { - constant(*self, Dim4::new(&[1, 1, 1, 1])) - } -} - -impl Convertable for Array { - type OutType = T; - - fn convert(&self) -> Array { - self.clone() - } -} - -macro_rules! overloaded_binary_func { - ($doc_str: expr, $fn_name: ident, $help_name: ident, $ffi_name: ident) => { - fn $help_name(lhs: &Array, rhs: &Array, batch: bool) -> Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { $ffi_name(&mut temp as *mut af_array, lhs.get(), rhs.get(), batch) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - #[doc=$doc_str] - /// - /// This is a binary elementwise operation. - /// - ///# Parameters - /// - /// - `arg1`is an argument that implements an internal trait `Convertable`. - /// - `arg2`is an argument that implements an internal trait `Convertable`. - /// - `batch` is an boolean that indicates if the current operation is an batch operation. - /// - /// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral - /// type. - /// - ///# Return Values - /// - /// An Array with results of the binary operation. - /// - ///# Important Notes - /// - /// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter - /// has no effect. - /// - /// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has - /// to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the - /// following criteria: - /// - Same number of elements in `arg1` and `arg2` along a given dimension/axis - /// - Only one element in `arg1` or `arg2` along a given dimension/axis - /// - /// - The trait `Convertable` essentially translates to a scalar native type on rust or Array. - pub fn $fn_name( - arg1: &T, - arg2: &U, - batch: bool, - ) -> Array< - <::OutType as ImplicitPromote<::OutType>>::Output, - > - where - T: Convertable, - U: Convertable, - ::OutType: ImplicitPromote<::OutType>, - ::OutType: ImplicitPromote<::OutType>, - { - let lhs = arg1.convert(); // Convert to Array - let rhs = arg2.convert(); // Convert to Array - match (lhs.is_scalar(), rhs.is_scalar()) { - (true, false) => { - let l = tile(&lhs, rhs.dims()); - $help_name(&l, &rhs, batch) - } - (false, true) => { - let r = tile(&rhs, lhs.dims()); - $help_name(&lhs, &r, batch) - } - _ => $help_name(&lhs, &rhs, batch), - } - } - }; -} - -overloaded_binary_func!("Addition of two Arrays", add, add_helper, af_add); -overloaded_binary_func!("Subtraction of two Arrays", sub, sub_helper, af_sub); -overloaded_binary_func!("Multiplication of two Arrays", mul, mul_helper, af_mul); -overloaded_binary_func!("Division of two Arrays", div, div_helper, af_div); -overloaded_binary_func!("Compute remainder from two Arrays", rem, rem_helper, af_rem); -overloaded_binary_func!("Compute left shift", shiftl, shiftl_helper, af_bitshiftl); -overloaded_binary_func!("Compute right shift", shiftr, shiftr_helper, af_bitshiftr); -overloaded_binary_func!( - "Compute modulo of two Arrays", - modulo, - modulo_helper, - af_mod -); -overloaded_binary_func!( - "Calculate atan2 of two Arrays", - atan2, - atan2_helper, - af_atan2 -); -overloaded_binary_func!( - "Create complex array from two Arrays", - cplx2, - cplx2_helper, - af_cplx2 -); -overloaded_binary_func!("Compute root", root, root_helper, af_root); -overloaded_binary_func!("Computer power", pow, pow_helper, af_pow); - -macro_rules! overloaded_logic_func { - ($doc_str: expr, $fn_name: ident, $help_name: ident, $ffi_name: ident) => { - fn $help_name(lhs: &Array, rhs: &Array, batch: bool) -> Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { $ffi_name(&mut temp as *mut af_array, lhs.get(), rhs.get(), batch) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - #[doc=$doc_str] - /// - /// This is a comparison operation. - /// - ///# Parameters - /// - /// - `arg1`is an argument that implements an internal trait `Convertable`. - /// - `arg2`is an argument that implements an internal trait `Convertable`. - /// - `batch` is an boolean that indicates if the current operation is an batch operation. - /// - /// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral - /// type. - /// - ///# Return Values - /// - /// An Array with results of the comparison operation a.k.a an Array of boolean values. - /// - ///# Important Notes - /// - /// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter - /// has no effect. - /// - /// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has - /// to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the - /// following criteria: - /// - Same number of elements in `arg1` and `arg2` along a given dimension/axis - /// - Only one element in `arg1` or `arg2` along a given dimension/axis - /// - /// - The trait `Convertable` essentially translates to a scalar native type on rust or Array. - pub fn $fn_name(arg1: &T, arg2: &U, batch: bool) -> Array - where - T: Convertable, - U: Convertable, - ::OutType: ImplicitPromote<::OutType>, - ::OutType: ImplicitPromote<::OutType>, - { - let lhs = arg1.convert(); // Convert to Array - let rhs = arg2.convert(); // Convert to Array - match (lhs.is_scalar(), rhs.is_scalar()) { - (true, false) => { - let l = tile(&lhs, rhs.dims()); - $help_name(&l, &rhs, batch) - } - (false, true) => { - let r = tile(&rhs, lhs.dims()); - $help_name(&lhs, &r, batch) - } - _ => $help_name(&lhs, &rhs, batch), - } - } - }; -} - -overloaded_logic_func!( - "Perform `less than` comparison operation", - lt, - lt_helper, - af_lt -); -overloaded_logic_func!( - "Perform `greater than` comparison operation", - gt, - gt_helper, - af_gt -); -overloaded_logic_func!( - "Perform `less than equals` comparison operation", - le, - le_helper, - af_le -); -overloaded_logic_func!( - "Perform `greater than equals` comparison operation", - ge, - ge_helper, - af_ge -); -overloaded_logic_func!( - "Perform `equals` comparison operation", - eq, - eq_helper, - af_eq -); -overloaded_logic_func!( - "Elementwise `not equals` comparison of two Arrays", - neq, - neq_helper, - af_neq -); -overloaded_logic_func!( - "Elementwise logical AND operation of two Arrays", - and, - and_helper, - af_and -); -overloaded_logic_func!( - "Elementwise logical OR operation of two Arrays", - or, - or_helper, - af_or -); - -fn clamp_helper( - inp: &Array, - lo: &Array, - hi: &Array, - batch: bool, -) -> Array<>::Output> -where - X: ImplicitPromote, - Y: ImplicitPromote, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_clamp( - &mut temp as *mut af_array, - inp.get(), - lo.get(), - hi.get(), - batch, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Clamp the values of Array -/// -/// # Parameters -/// -/// - `arg1`is an argument that implements an internal trait `Convertable`. -/// - `arg2`is an argument that implements an internal trait `Convertable`. -/// - `batch` is an boolean that indicates if the current operation is an batch operation. -/// -/// Both parameters `arg1` and `arg2` can be either an Array or a value of rust integral -/// type. -/// -/// # Return Values -/// -/// An Array with results of the binary operation. -/// -/// # Important Notes -/// -/// - If shape/dimensions of `arg1` and `arg2` are same, the value of `batch` parameter -/// has no effect. -/// -/// - If shape/dimensions of `arg1` and `arg2` are different, the value of `batch` has -/// to be set to `true`. In this case, the shapes of `arg1` and `arg2` have to satisfy the -/// following criteria: -/// - Same number of elements in `arg1` and `arg2` along a given dimension/axis -/// - Only one element in `arg1` or `arg2` along a given dimension/axis -/// -/// - The trait `Convertable` essentially translates to a scalar native type on rust or Array. -pub fn clamp( - input: &Array, - arg1: &C, - arg2: &C, - batch: bool, -) -> Array<::OutType>>::Output> -where - T: ImplicitPromote<::OutType>, - C: Convertable, - ::OutType: ImplicitPromote, -{ - let lo = arg1.convert(); // Convert to Array - let hi = arg2.convert(); // Convert to Array - match (lo.is_scalar(), hi.is_scalar()) { - (true, false) => { - let l = tile(&lo, hi.dims()); - clamp_helper(input, &l, &hi, batch) - } - (false, true) => { - let r = tile(&hi, lo.dims()); - clamp_helper(input, &lo, &r, batch) - } - (true, true) => { - let l = tile(&lo, input.dims()); - let r = tile(&hi, input.dims()); - clamp_helper(input, &l, &r, batch) - } - _ => clamp_helper(input, &lo, &hi, batch), - } -} - -macro_rules! arith_rhs_scalar_func { - ($op_name:ident, $fn_name: ident) => { - // Implement (&Array op_name rust_type) - impl<'f, T, U> $op_name for &'f Array - where - T: ImplicitPromote, - U: ImplicitPromote + Clone + ConstGenerator, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: U) -> Self::Output { - let temp = rhs.clone(); - $fn_name(self, &temp, false) - } - } - - // Implement (Array op_name rust_type) - impl $op_name for Array - where - T: ImplicitPromote, - U: ImplicitPromote + Clone + ConstGenerator, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: U) -> Self::Output { - let temp = rhs.clone(); - $fn_name(&self, &temp, false) - } - } - }; -} - -macro_rules! arith_lhs_scalar_func { - ($rust_type: ty, $op_name: ident, $fn_name: ident) => { - // Implement (rust_type op_name &Array) - impl<'f, T> $op_name<&'f Array> for $rust_type - where - T: ImplicitPromote<$rust_type>, - $rust_type: ImplicitPromote, - { - type Output = Array<<$rust_type as ImplicitPromote>::Output>; - - fn $fn_name(self, rhs: &'f Array) -> Self::Output { - $fn_name(&self, rhs, false) - } - } - - // Implement (rust_type op_name Array) - impl $op_name> for $rust_type - where - T: ImplicitPromote<$rust_type>, - $rust_type: ImplicitPromote, - { - type Output = Array<<$rust_type as ImplicitPromote>::Output>; - - fn $fn_name(self, rhs: Array) -> Self::Output { - $fn_name(&self, &rhs, false) - } - } - }; -} - -arith_rhs_scalar_func!(Add, add); -arith_rhs_scalar_func!(Sub, sub); -arith_rhs_scalar_func!(Mul, mul); -arith_rhs_scalar_func!(Div, div); - -macro_rules! arith_scalar_spec { - ($ty_name:ty) => { - arith_lhs_scalar_func!($ty_name, Add, add); - arith_lhs_scalar_func!($ty_name, Sub, sub); - arith_lhs_scalar_func!($ty_name, Mul, mul); - arith_lhs_scalar_func!($ty_name, Div, div); - }; -} - -arith_scalar_spec!(Complex); -arith_scalar_spec!(Complex); -arith_scalar_spec!(f64); -arith_scalar_spec!(f32); -arith_scalar_spec!(f16); -arith_scalar_spec!(u64); -arith_scalar_spec!(i64); -arith_scalar_spec!(u32); -arith_scalar_spec!(i32); -arith_scalar_spec!(u8); - -macro_rules! arith_func { - ($op_name:ident, $fn_name:ident, $delegate:ident) => { - impl $op_name> for Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: Array) -> Self::Output { - $delegate(&self, &rhs, false) - } - } - - impl<'a, A, B> $op_name<&'a Array> for Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: &'a Array) -> Self::Output { - $delegate(&self, rhs, false) - } - } - - impl<'a, A, B> $op_name> for &'a Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: Array) -> Self::Output { - $delegate(self, &rhs, false) - } - } - - impl<'a, 'b, A, B> $op_name<&'a Array> for &'b Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $fn_name(self, rhs: &'a Array) -> Self::Output { - $delegate(self, rhs, false) - } - } - }; -} - -arith_func!(Add, add, add); -arith_func!(Sub, sub, sub); -arith_func!(Mul, mul, mul); -arith_func!(Div, div, div); -arith_func!(Rem, rem, rem); -arith_func!(Shl, shl, shiftl); -arith_func!(Shr, shr, shiftr); -arith_func!(BitAnd, bitand, bitand); -arith_func!(BitOr, bitor, bitor); -arith_func!(BitXor, bitxor, bitxor); - -macro_rules! bitshift_scalar_func { - ($rust_type: ty, $trait_name: ident, $op_name: ident) => { - impl $trait_name<$rust_type> for Array - where - T: ImplicitPromote<$rust_type>, - $rust_type: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $op_name(self, rhs: $rust_type) -> Self::Output { - let op2 = constant(rhs, self.dims()); - self.$op_name(op2) - } - } - impl<'f, T> $trait_name<$rust_type> for &'f Array - where - T: ImplicitPromote<$rust_type>, - $rust_type: ImplicitPromote, - { - type Output = Array<>::Output>; - - fn $op_name(self, rhs: $rust_type) -> Self::Output { - let op2 = constant(rhs, self.dims()); - self.$op_name(op2) - } - } - }; -} - -macro_rules! shift_spec { - ($trait_name: ident, $op_name: ident) => { - bitshift_scalar_func!(u64, $trait_name, $op_name); - bitshift_scalar_func!(u32, $trait_name, $op_name); - bitshift_scalar_func!(u16, $trait_name, $op_name); - bitshift_scalar_func!(u8, $trait_name, $op_name); - }; -} - -shift_spec!(Shl, shl); -shift_spec!(Shr, shr); - -#[cfg(op_assign)] -mod op_assign { - - use super::*; - use crate::core::{assign_gen, Array, Indexer, Seq}; - use std::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign}; - use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign}; - - macro_rules! arith_assign_func { - ($op_name:ident, $fn_name:ident, $func: ident) => { - impl $op_name> for Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - fn $fn_name(&mut self, rhs: Array) { - let tmp_seq = Seq::::default(); - let mut idxrs = Indexer::default(); - for n in 0..self.numdims() { - idxrs.set_index(&tmp_seq, n, Some(false)); - } - let opres = $func(self as &Array, &rhs, false).cast::(); - assign_gen(self, &idxrs, &opres); - } - } - }; - } - - arith_assign_func!(AddAssign, add_assign, add); - arith_assign_func!(SubAssign, sub_assign, sub); - arith_assign_func!(MulAssign, mul_assign, mul); - arith_assign_func!(DivAssign, div_assign, div); - arith_assign_func!(RemAssign, rem_assign, rem); - arith_assign_func!(ShlAssign, shl_assign, shiftl); - arith_assign_func!(ShrAssign, shr_assign, shiftr); - - macro_rules! shift_assign_func { - ($rust_type:ty, $trait_name:ident, $op_name:ident, $func:ident) => { - impl $trait_name<$rust_type> for Array - where - $rust_type: ImplicitPromote, - T: ImplicitPromote<$rust_type, Output = T>, - { - fn $op_name(&mut self, rhs: $rust_type) { - let mut temp = $func(self, &rhs, false); - mem::swap(self, &mut temp); - } - } - }; - } - - macro_rules! shift_assign_spec { - ($trait_name: ident, $op_name: ident, $func:ident) => { - shift_assign_func!(u64, $trait_name, $op_name, $func); - shift_assign_func!(u32, $trait_name, $op_name, $func); - shift_assign_func!(u16, $trait_name, $op_name, $func); - shift_assign_func!(u8, $trait_name, $op_name, $func); - }; - } - - shift_assign_spec!(ShlAssign, shl_assign, shiftl); - shift_assign_spec!(ShrAssign, shr_assign, shiftr); - - macro_rules! bit_assign_func { - ($op_name:ident, $fn_name:ident, $func: ident) => { - impl $op_name> for Array - where - A: ImplicitPromote, - B: ImplicitPromote, - { - fn $fn_name(&mut self, rhs: Array) { - let tmp_seq = Seq::::default(); - let mut idxrs = Indexer::default(); - for n in 0..self.numdims() { - idxrs.set_index(&tmp_seq, n, Some(false)); - } - let opres = $func(self as &Array, &rhs, false).cast::(); - assign_gen(self, &idxrs, &opres); - } - } - }; - } - - bit_assign_func!(BitAndAssign, bitand_assign, bitand); - bit_assign_func!(BitOrAssign, bitor_assign, bitor); - bit_assign_func!(BitXorAssign, bitxor_assign, bitxor); -} - -///Implement negation trait for Array -impl Neg for Array -where - T: Zero + ConstGenerator, -{ - type Output = Array; - - fn neg(self) -> Self::Output { - let cnst = constant(T::zero(), self.dims()); - sub(&cnst, &self, true) - } -} - -/// Perform bitwise complement on all values of Array -pub fn bitnot(input: &Array) -> Array -where - T: HasAfEnum + IntegralType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_bitnot(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} diff --git a/src/core/array.rs b/src/core/array.rs deleted file mode 100644 index 7ee6579ba..000000000 --- a/src/core/array.rs +++ /dev/null @@ -1,1223 +0,0 @@ -use super::defines::{AfError, Backend, DType}; -use super::dim4::Dim4; -use super::error::HANDLE_ERROR; -use super::util::{af_array, dim_t, free_host, void_ptr, HasAfEnum}; - -use libc::{c_char, c_int, c_longlong, c_uint, c_void}; -use std::ffi::{CStr, CString}; -use std::fmt; -use std::marker::PhantomData; - -// Some unused functions from array.h in C-API of ArrayFire -// af_copy_array -// af_write_array -// af_get_data_ref_count - -extern "C" { - fn af_create_array( - out: *mut af_array, - data: *const c_void, - ndims: c_uint, - dims: *const dim_t, - aftype: c_uint, - ) -> c_int; - - fn af_create_handle( - out: *mut af_array, - ndims: c_uint, - dims: *const dim_t, - aftype: c_uint, - ) -> c_int; - - fn af_device_array( - out: *mut af_array, - data: *mut c_void, - ndims: c_uint, - dims: *const dim_t, - aftype: c_uint, - ) -> c_int; - - fn af_get_elements(out: *mut dim_t, arr: af_array) -> c_int; - - fn af_get_type(out: *mut c_uint, arr: af_array) -> c_int; - - fn af_get_dims( - dim0: *mut c_longlong, - dim1: *mut c_longlong, - dim2: *mut c_longlong, - dim3: *mut c_longlong, - arr: af_array, - ) -> c_int; - - fn af_get_numdims(result: *mut c_uint, arr: af_array) -> c_int; - - fn af_is_empty(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_scalar(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_row(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_column(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_vector(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_complex(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_real(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_double(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_single(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_half(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_integer(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_bool(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_realfloating(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_floating(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_linear(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_owner(result: *mut bool, arr: af_array) -> c_int; - - fn af_is_sparse(result: *mut bool, arr: af_array) -> c_int; - - fn af_get_data_ptr(data: *mut c_void, arr: af_array) -> c_int; - - fn af_eval(arr: af_array) -> c_int; - - fn af_eval_multiple(num: c_int, arrays: *const af_array) -> c_int; - - fn af_set_manual_eval_flag(flag: c_int) -> c_int; - - fn af_get_manual_eval_flag(flag: *mut c_int) -> c_int; - - fn af_retain_array(out: *mut af_array, arr: af_array) -> c_int; - - fn af_copy_array(out: *mut af_array, arr: af_array) -> c_int; - - fn af_release_array(arr: af_array) -> c_int; - - //fn af_print_array(arr: af_array) -> c_int; - - fn af_print_array_gen(exp: *const c_char, arr: af_array, precision: c_int) -> c_int; - - fn af_cast(out: *mut af_array, arr: af_array, aftype: c_uint) -> c_int; - - fn af_get_backend_id(backend: *mut c_uint, input: af_array) -> c_int; - - fn af_get_device_id(device: *mut c_int, input: af_array) -> c_int; - - fn af_create_strided_array( - arr: *mut af_array, - data: *const c_void, - offset: dim_t, - ndims: c_uint, - dims: *const dim_t, - strides: *const dim_t, - aftype: c_uint, - stype: c_uint, - ) -> c_int; - - fn af_get_strides( - s0: *mut dim_t, - s1: *mut dim_t, - s2: *mut dim_t, - s3: *mut dim_t, - arr: af_array, - ) -> c_int; - - fn af_get_offset(offset: *mut dim_t, arr: af_array) -> c_int; - - fn af_lock_array(arr: af_array) -> c_int; - - fn af_unlock_array(arr: af_array) -> c_int; - - fn af_get_device_ptr(ptr: *mut void_ptr, arr: af_array) -> c_int; - - fn af_get_allocated_bytes(result: *mut usize, arr: af_array) -> c_int; - - fn af_array_to_string( - ostr: *mut *mut c_char, - exp: *const c_char, - arr: af_array, - precision: c_int, - transpose: bool, - ) -> c_int; -} - -/// A multidimensional data container -/// -/// Currently, `Array` objects support data up to four dimensions. -/// -/// All operations on arrays (including creation) require that `T: HasAfEnum`, -/// meaning that `T` must be one of the numerical datatypes supported by Arrayfire. -/// -/// ## Sharing Across Threads -/// -/// While sharing an Array with other threads, there is no need to wrap -/// this in an Arc object unless only one such object is required to exist. -/// The reason being that ArrayFire's internal Array is appropriately reference -/// counted in thread safe manner. However, if you need to modify Array object, -/// then please do wrap the object using a Mutex or Read-Write lock. -/// -/// Examples on how to share Array across threads is illustrated in our -/// [book](http://arrayfire.org/arrayfire-rust/book/multi-threading.html) -/// -/// ### NOTE -/// -/// All operators(traits) from std::ops module implemented for Array object -/// carry out element wise operations. For example, `*` does multiplication of -/// elements at corresponding locations in two different Arrays. -pub struct Array { - handle: af_array, - /// The phantom marker denotes the - /// allocation of data on compute device - _marker: PhantomData, -} - -/// Enable safely moving Array objects across threads -unsafe impl Send for Array {} - -unsafe impl Sync for Array {} - -macro_rules! is_func { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - pub fn $fn_name(&self) -> bool { - unsafe { - let mut ret_val: bool = false; - let err_val = $ffi_fn(&mut ret_val as *mut bool, self.handle); - HANDLE_ERROR(AfError::from(err_val)); - ret_val - } - } - }; -} - -impl Array -where - T: HasAfEnum, -{ - /// Constructs a new Array object - /// - /// # Examples - /// - /// An example of creating an Array from f32 array - /// - /// ```rust - /// use arrayfire::{Array, Dim4, print}; - /// let values: [f32; 3] = [1.0, 2.0, 3.0]; - /// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); - /// print(&indices); - /// ``` - /// An example of creating an Array from half::f16 array - /// - /// ```rust - /// use arrayfire::{Array, Dim4, is_half_available, print}; - /// use half::f16; - /// - /// let values: [f32; 3] = [1.0, 2.0, 3.0]; - /// - /// if is_half_available(0) { // Default device is 0, hence the argument - /// let half_values = values.iter().map(|&x| f16::from_f32(x)).collect::>(); - /// - /// let hvals = Array::new(&half_values, Dim4::new(&[3, 1, 1, 1])); - /// - /// print(&hvals); - /// } else { - /// println!("Half support isn't available on this device"); - /// } - /// ``` - /// - pub fn new(slice: &[T], dims: Dim4) -> Self { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_array( - &mut temp as *mut af_array, - slice.as_ptr() as *const c_void, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const c_longlong, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - /// Constructs a new Array object from strided data - /// - /// The data pointed by the slice passed to this function can possibily be offseted using an additional `offset` parameter. - pub fn new_strided(slice: &[T], offset: i64, dims: Dim4, strides: Dim4) -> Self { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_strided_array( - &mut temp as *mut af_array, - slice.as_ptr() as *const c_void, - offset as dim_t, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const c_longlong, - strides.get().as_ptr() as *const c_longlong, - aftype as c_uint, - 1_u32, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - /// Constructs a new Array object of specified dimensions and type - /// - /// # Examples - /// - /// ```rust - /// use arrayfire::{Array, Dim4}; - /// let garbage_vals = Array::::new_empty(Dim4::new(&[3, 1, 1, 1])); - /// ``` - pub fn new_empty(dims: Dim4) -> Self { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_handle( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const c_longlong, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - /// Constructs a new Array object from device pointer - /// - /// The example show cases the usage using CUDA API, but usage of this function will - /// be similar in CPU and OpenCL backends also. In the case of OpenCL backend, the pointer - /// would be cl_mem. A short example of how to create an Array from device pointer is - /// shown below but for detailed set of examples, please check out the tutorial book - /// pages: - /// - [Interoperability with CUDA][1] - /// - [Interoperability with OpenCL][2] - /// - /// [1]: http://arrayfire.org/arrayfire-rust/book/cuda-interop.html - /// [2]: http://arrayfire.org/arrayfire-rust/book/opencl-interop.html - /// - /// # Examples - /// - /// An example of creating an Array device pointer using - /// [rustacuda](https://github.com/bheisler/RustaCUDA) crate. The - /// example has to be copied to a `bin` crate with following contents in Cargo.toml - /// to run successfully. Note that, all required setup for rustacuda and arrayfire crate - /// have to completed first. - /// ```text - /// [package] - /// .... - /// [dependencies] - /// rustacuda = "0.1" - /// rustacuda_derive = "0.1" - /// rustacuda_core = "0.1" - /// arrayfire = "3.7.*" - /// ``` - /// - /// ```rust,ignore - ///use arrayfire::*; - ///use rustacuda::*; - ///use rustacuda::prelude::*; - /// - ///fn main() { - /// let v: Vec<_> = (0u8 .. 100).map(f32::from).collect(); - /// - /// rustacuda::init(CudaFlags::empty()); - /// let device = Device::get_device(0).unwrap(); - /// let context = Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, - /// device).unwrap(); - /// // Approach 1 - /// { - /// let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap(); - /// - /// let array_dptr = Array::new_from_device_ptr( - /// buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10)); - /// - /// af_print!("array_dptr", &array_dptr); - /// - /// array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership - /// } - /// - /// // Approach 2 - /// { - /// let mut dptr: *mut f32 = std::ptr::null_mut(); - /// unsafe { - /// dptr = memory::cuda_malloc::(10*10).unwrap().as_raw_mut(); - /// } - /// let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10)); - /// // note that values might be garbage in the memory pointed out by dptr - /// // in this example as it is allocated but not initialized prior to passing - /// // along to arrayfire::Array::new* - /// - /// // After ArrayFire takes over ownership of the pointer, you can use other - /// // arrayfire functions as usual. - /// af_print!("array_dptr", &array_dptr); - /// } - ///} - /// ``` - pub fn new_from_device_ptr(dev_ptr: *mut T, dims: Dim4) -> Self { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_device_array( - &mut temp as *mut af_array, - dev_ptr as *mut c_void, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - /// Returns the backend of the Array - /// - /// # Return Values - /// - /// Returns an value of type `Backend` which indicates which backend - /// was active when Array was created. - pub fn get_backend(&self) -> Backend { - let mut ret_val: u32 = 0; - let err_val = unsafe { af_get_backend_id(&mut ret_val as *mut c_uint, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - match (err_val, ret_val) { - (0, 1) => Backend::CPU, - (0, 2) => Backend::CUDA, - (0, 3) => Backend::OPENCL, - _ => Backend::DEFAULT, - } - } - - /// Returns the device identifier(integer) on which the Array was created - /// - /// # Return Values - /// - /// Return the device id on which Array was created. - pub fn get_device_id(&self) -> i32 { - let mut ret_val: i32 = 0; - let err_val = unsafe { af_get_device_id(&mut ret_val as *mut c_int, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val - } - - /// Returns the number of elements in the Array - pub fn elements(&self) -> usize { - let mut ret_val: dim_t = 0; - let err_val = unsafe { af_get_elements(&mut ret_val as *mut dim_t, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val as usize - } - - /// Returns the Array data type - pub fn get_type(&self) -> DType { - let mut ret_val: u32 = 0; - let err_val = unsafe { af_get_type(&mut ret_val as *mut c_uint, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - DType::from(ret_val) - } - - /// Returns the dimensions of the Array - pub fn dims(&self) -> Dim4 { - let mut ret0: i64 = 0; - let mut ret1: i64 = 0; - let mut ret2: i64 = 0; - let mut ret3: i64 = 0; - let err_val = unsafe { - af_get_dims( - &mut ret0 as *mut dim_t, - &mut ret1 as *mut dim_t, - &mut ret2 as *mut dim_t, - &mut ret3 as *mut dim_t, - self.handle, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64]) - } - - /// Returns the strides of the Array - pub fn strides(&self) -> Dim4 { - let mut ret0: i64 = 0; - let mut ret1: i64 = 0; - let mut ret2: i64 = 0; - let mut ret3: i64 = 0; - let err_val = unsafe { - af_get_strides( - &mut ret0 as *mut dim_t, - &mut ret1 as *mut dim_t, - &mut ret2 as *mut dim_t, - &mut ret3 as *mut dim_t, - self.handle, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64]) - } - - /// Returns the number of dimensions of the Array - pub fn numdims(&self) -> u32 { - let mut ret_val: u32 = 0; - let err_val = unsafe { af_get_numdims(&mut ret_val as *mut c_uint, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val - } - - /// Returns the offset to the pointer from where data begins - pub fn offset(&self) -> i64 { - let mut ret_val: i64 = 0; - let err_val = unsafe { af_get_offset(&mut ret_val as *mut dim_t, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val - } - - /// Returns the native FFI handle for Rust object `Array` - pub(crate) unsafe fn get(&self) -> af_array { - self.handle - } - - /// Set the native FFI handle for Rust object `Array` - pub fn set(&mut self, handle: af_array) { - self.handle = handle; - } - - /// Copies the data from the Array to the mutable slice `data` - /// - /// # Examples - /// - /// Basic case - /// ``` - /// # use arrayfire::{Array,Dim4,HasAfEnum}; - /// let a:Vec = vec![0,1,2,3,4,5,6,7,8]; - /// let b = Array::::new(&a,Dim4::new(&[3,3,1,1])); - /// let mut c = vec!(u8::default();b.elements()); - /// b.host(&mut c); - /// assert_eq!(c,a); - /// ``` - /// Generic case - /// ``` - /// # use arrayfire::{Array,Dim4,HasAfEnum}; - /// fn to_vec(array:&Array) -> Vec { - /// let mut vec = vec!(T::default();array.elements()); - /// array.host(&mut vec); - /// return vec; - /// } - /// - /// let a = Array::::new(&[0,1,2,3,4,5,6,7,8],Dim4::new(&[3,3,1,1])); - /// let b:Vec = vec![0,1,2,3,4,5,6,7,8]; - /// assert_eq!(to_vec(&a),b); - /// ``` - pub fn host(&self, data: &mut [O]) { - if data.len() != self.elements() { - HANDLE_ERROR(AfError::ERR_SIZE); - } - - let err_val = unsafe { af_get_data_ptr(data.as_mut_ptr() as *mut c_void, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Evaluates any pending lazy expressions that represent the data in the Array object - pub fn eval(&self) { - let err_val = unsafe { af_eval(self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Makes an copy of the Array - /// - /// This does a deep copy of the data into a new Array - pub fn copy(&self) -> Self { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_copy_array(&mut temp as *mut af_array, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - is_func!("Check if Array is empty", is_empty, af_is_empty); - is_func!("Check if Array is scalar", is_scalar, af_is_scalar); - is_func!("Check if Array is a row", is_row, af_is_row); - is_func!("Check if Array is a column", is_column, af_is_column); - is_func!("Check if Array is a vector", is_vector, af_is_vector); - - is_func!( - "Check if Array is of real (not complex) type", - is_real, - af_is_real - ); - is_func!( - "Check if Array is of complex type", - is_complex, - af_is_complex - ); - - is_func!( - "Check if Array's numerical type is of double precision", - is_double, - af_is_double - ); - is_func!( - "Check if Array's numerical type is of single precision", - is_single, - af_is_single - ); - is_func!( - "Check if Array's numerical type is of half precision", - is_half, - af_is_half - ); - is_func!( - "Check if Array is of integral type", - is_integer, - af_is_integer - ); - is_func!("Check if Array is of boolean type", is_bool, af_is_bool); - - is_func!( - "Check if Array is floating point real(not complex) data type", - is_realfloating, - af_is_realfloating - ); - is_func!( - "Check if Array is floating point type, either real or complex data", - is_floating, - af_is_floating - ); - - is_func!( - "Check if Array's memory layout is continuous and one dimensional", - is_linear, - af_is_linear - ); - is_func!("Check if Array is a sparse matrix", is_sparse, af_is_sparse); - is_func!( - "Check if Array's memory is owned by it and not a view of another Array", - is_owner, - af_is_owner - ); - - /// Cast the Array data type to `target_type` - pub fn cast(&self) -> Array { - let trgt_type = O::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_cast(&mut temp as *mut af_array, self.handle, trgt_type as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - - /// Lock the device buffer in the memory manager - /// - /// Locked buffers are not freed by memory manager until unlock is called. - pub fn lock(&self) { - let err_val = unsafe { af_lock_array(self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Unlock the device buffer in the memory manager - /// - /// This function will give back the control over the device pointer to the - /// memory manager. - pub fn unlock(&self) { - let err_val = unsafe { af_unlock_array(self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Get the device pointer and lock the buffer in memory manager - /// - /// The device pointer is not freed by memory manager until unlock is called. - /// - /// # Safety - /// - /// Using the function returns a pointer(CPU)/GPU-memory-pointer(CUDA)/cl_mem(OpenCL). - /// Use this function only when you know what to do further with returned object. - pub unsafe fn device_ptr(&self) -> void_ptr { - let mut temp: void_ptr = std::ptr::null_mut(); - let err_val = af_get_device_ptr(&mut temp as *mut void_ptr, self.handle); - HANDLE_ERROR(AfError::from(err_val)); - temp - } - - /// Get the size of physical allocated bytes. - /// - /// This function will return the size of the parent/owner if the current Array object is an - /// indexed Array. - pub fn get_allocated_bytes(&self) -> usize { - let mut temp: usize = 0; - let err_val = unsafe { af_get_allocated_bytes(&mut temp as *mut usize, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - temp - } - - /// Fetch Array as String - #[allow(clippy::inherent_to_string)] - pub fn to_string(&self) -> String { - let cname = CString::new("test").unwrap(); - let mut tmp: *mut c_char = ::std::ptr::null_mut(); - let err_val = unsafe { - af_array_to_string( - &mut tmp, - cname.to_bytes_with_nul().as_ptr() as *const c_char, - self.get(), - 4, - true, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - let result: String = unsafe { CStr::from_ptr(tmp).to_string_lossy().into_owned() }; - free_host(tmp); - result - } -} - -/// Used for creating Array object from native -/// resource id, an 64 bit integer -#[allow(clippy::from_over_into)] -impl Into> for af_array { - fn into(self) -> Array { - Array { - handle: self, - _marker: PhantomData, - } - } -} - -/// Returns a new Array object after incrementing the reference count of native resource -/// -/// Cloning an Array does not do a deep copy of the underlying array data. It increments the -/// reference count of native resource and returns you the new reference in the form a new Array -/// object. -/// -/// To create a deep copy use -/// [copy()](./struct.Array.html#method.copy) -impl Clone for Array -where - T: HasAfEnum, -{ - fn clone(&self) -> Self { - let mut temp: af_array = std::ptr::null_mut(); - let ret_val = unsafe { af_retain_array(&mut temp as *mut af_array, self.handle) }; - match ret_val { - 0 => temp.into(), - _ => panic!("Weak copy of Array failed with error code: {}", ret_val), - } - } -} - -/// To free resources when Array goes out of scope -impl Drop for Array { - fn drop(&mut self) { - let ret_val = unsafe { af_release_array(self.handle) }; - match ret_val { - 0 => (), - _ => panic!("Array drop failed with error code: {}", ret_val), - } - } -} - -/// Print data in the Array -/// -/// # Parameters -/// -/// - `input` is the Array to be printed -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, print, randu}; -/// println!("Create a 5-by-3 matrix of random floats on the GPU"); -/// let dims = Dim4::new(&[5, 3, 1, 1]); -/// let a = randu::(dims); -/// print(&a); -/// ``` -/// -/// The sample output will look like below: -/// -/// ```text -/// [5 3 1 1] -/// 0.7402 0.4464 0.7762 -/// 0.9210 0.6673 0.2948 -/// 0.0390 0.1099 0.7140 -/// 0.9690 0.4702 0.3585 -/// 0.9251 0.5132 0.6814 -/// ``` -pub fn print(input: &Array) { - let emptystring = CString::new("").unwrap(); - - let err_val = unsafe { - af_print_array_gen( - emptystring.to_bytes_with_nul().as_ptr() as *const c_char, - input.get(), - 4, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Generalized Array print function -/// -/// Use this function to print Array data with arbitrary preicsion -/// -/// # Parameters -/// -/// - `msg` is message to be printed before printing the Array data -/// - `input` is the Array to be printed -/// - `precision` is data precision with which Array has to be printed -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, print_gen, randu}; -/// println!("Create a 5-by-3 matrix of random floats on the GPU"); -/// let dims = Dim4::new(&[5, 3, 1, 1]); -/// let a = randu::(dims); -/// print_gen(String::from("Random Array"), &a, Some(6)); -/// ``` -/// -/// The sample output will look like below: -/// -/// ```text -/// Random Array -/// -/// [5 3 1 1] -/// 0.740276 0.446440 0.776202 -/// 0.921094 0.667321 0.294810 -/// 0.039014 0.109939 0.714090 -/// 0.969058 0.470269 0.358590 -/// 0.925181 0.513225 0.681451 -/// ``` -pub fn print_gen(msg: String, input: &Array, precision: Option) { - let emptystring = CString::new(msg.as_bytes()).unwrap(); - - let err_val = unsafe { - af_print_array_gen( - emptystring.to_bytes_with_nul().as_ptr() as *const c_char, - input.get(), - precision.unwrap_or(4), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// evaluate multiple arrays -/// -/// Use this function to evaluate multiple arrays in single call -/// -/// # Parameters -/// -/// - `inputs` are the list of arrays to be evaluated -pub fn eval_multiple(inputs: Vec<&Array>) { - let mut v = Vec::new(); - for i in inputs { - unsafe { v.push(i.get()) }; - } - - let err_val = unsafe { af_eval_multiple(v.len() as c_int, v.as_ptr() as *const af_array) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Set eval flag value -/// -/// This function can be used to toggle on/off the manual evaluation of arrays. -/// -/// # Parameters -/// -/// - `flag` is a boolean value indicating manual evaluation setting -pub fn set_manual_eval(flag: bool) { - let err_val = unsafe { af_set_manual_eval_flag(flag as c_int) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get eval flag value -/// -/// This function can be used to find out if manual evaluation of arrays is -/// turned on or off. -/// -/// # Return Values -/// -/// A boolean indicating manual evaluation setting. -pub fn is_eval_manual() -> bool { - let mut ret_val: i32 = 0; - let err_val = unsafe { af_get_manual_eval_flag(&mut ret_val as *mut c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val > 0 -} - -/// Prints data type, shape and data of a given Array in programming friendly context -/// -/// Used via println macro or formatter -impl fmt::Debug for Array -where - T: HasAfEnum, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - let mut vec = vec![T::default(); self.elements()]; - self.host(&mut vec); - f.debug_struct("Array") - .field("dtype", &self.get_type()) - .field("shape", &self.dims()) - .field("strides", &self.strides()) - .field("offset", &self.offset()) - .field("device_id", &self.get_device_id()) - .field("data", &vec) - .finish() - } else { - f.debug_struct("Array") - .field("dtype", &self.get_type()) - .field("shape", &self.dims()) - .field("af_array", unsafe { &self.get() }) - .finish() - } - } -} - -#[cfg(feature = "afserde")] -mod afserde { - // Reimport required from super scope - use super::{Array, DType, Dim4, HasAfEnum}; - - use serde::de::{Deserializer, Error, Unexpected}; - use serde::ser::Serializer; - use serde::{Deserialize, Serialize}; - - #[derive(Debug, Serialize, Deserialize)] - struct ArrayOnHost { - dtype: DType, - shape: Dim4, - data: Vec, - } - - /// Serialize Implementation of Array - impl Serialize for Array - where - T: Serialize + HasAfEnum, - { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut vec = vec![T::default(); self.elements()]; - self.host(&mut vec); - let arr_on_host = ArrayOnHost { - dtype: self.get_type(), - shape: self.dims().clone(), - data: vec, - }; - arr_on_host.serialize(serializer) - } - } - - /// Deserialize Implementation of Array - impl<'de, T> Deserialize<'de> for Array - where - T: Deserialize<'de> + HasAfEnum, - { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - match ArrayOnHost::::deserialize(deserializer) { - Ok(arr_on_host) => { - let read_dtype = arr_on_host.dtype; - let expected_dtype = T::get_af_dtype(); - if expected_dtype != read_dtype { - let error_msg = format!( - "data type is {:?}, deserialized type is {:?}", - expected_dtype, read_dtype - ); - return Err(Error::invalid_value(Unexpected::Enum, &error_msg.as_str())); - } - Ok(Array::::new( - &arr_on_host.data, - arr_on_host.shape.clone(), - )) - } - Err(err) => Err(err), - } - } - } -} - -#[cfg(test)] -mod tests { - use super::super::array::print; - use super::super::data::constant; - use super::super::device::{info, set_device, sync}; - use crate::dim4; - use std::sync::{mpsc, Arc, RwLock}; - use std::thread; - - #[test] - fn thread_move_array() { - // ANCHOR: move_array_to_thread - set_device(0); - info(); - let mut a = constant(1, dim4!(3, 3)); - - let handle = thread::spawn(move || { - //set_device to appropriate device id is required in each thread - set_device(0); - - println!("\nFrom thread {:?}", thread::current().id()); - - a += constant(2, dim4!(3, 3)); - print(&a); - }); - - //Need to join other threads as main thread holds arrayfire context - handle.join().unwrap(); - // ANCHOR_END: move_array_to_thread - } - - #[test] - fn thread_borrow_array() { - set_device(0); - info(); - let a = constant(1i32, dim4!(3, 3)); - - let handle = thread::spawn(move || { - set_device(0); //set_device to appropriate device id is required in each thread - println!("\nFrom thread {:?}", thread::current().id()); - print(&a); - }); - //Need to join other threads as main thread holds arrayfire context - handle.join().unwrap(); - } - - // ANCHOR: multiple_threads_enum_def - #[derive(Debug, Copy, Clone)] - enum Op { - Add, - Sub, - Div, - Mul, - } - // ANCHOR_END: multiple_threads_enum_def - - #[test] - fn read_from_multiple_threads() { - // ANCHOR: read_from_multiple_threads - let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; - - // Set active GPU/device on main thread on which - // subsequent Array objects are created - set_device(0); - - // ArrayFire Array's are internally maintained via atomic reference counting - // Thus, they need no Arc wrapping while moving to another thread. - // Just call clone method on the object and share the resulting clone object - let a = constant(1.0f32, dim4!(3, 3)); - let b = constant(2.0f32, dim4!(3, 3)); - - let threads: Vec<_> = ops - .into_iter() - .map(|op| { - let x = a.clone(); - let y = b.clone(); - thread::spawn(move || { - set_device(0); //Both of objects are created on device 0 earlier - match op { - Op::Add => { - let _c = x + y; - } - Op::Sub => { - let _c = x - y; - } - Op::Div => { - let _c = x / y; - } - Op::Mul => { - let _c = x * y; - } - } - sync(0); - thread::sleep(std::time::Duration::new(1, 0)); - }) - }) - .collect(); - for child in threads { - let _ = child.join(); - } - // ANCHOR_END: read_from_multiple_threads - } - - #[test] - fn access_using_rwlock() { - // ANCHOR: access_using_rwlock - let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; - - // Set active GPU/device on main thread on which - // subsequent Array objects are created - set_device(0); - - let c = constant(0.0f32, dim4!(3, 3)); - let a = constant(1.0f32, dim4!(3, 3)); - let b = constant(2.0f32, dim4!(3, 3)); - - // Move ownership to RwLock and wrap in Arc since same object is to be modified - let c_lock = Arc::new(RwLock::new(c)); - - // a and b are internally reference counted by ArrayFire. Unless there - // is prior known need that they may be modified, you can simply clone - // the objects pass them to threads - - let threads: Vec<_> = ops - .into_iter() - .map(|op| { - let x = a.clone(); - let y = b.clone(); - - let wlock = c_lock.clone(); - thread::spawn(move || { - //Both of objects are created on device 0 in main thread - //Every thread needs to set the device that it is going to - //work on. Note that all Array objects must have been created - //on same device as of date this is written on. - set_device(0); - if let Ok(mut c_guard) = wlock.write() { - match op { - Op::Add => { - *c_guard += x + y; - } - Op::Sub => { - *c_guard += x - y; - } - Op::Div => { - *c_guard += x / y; - } - Op::Mul => { - *c_guard += x * y; - } - } - } - }) - }) - .collect(); - - for child in threads { - let _ = child.join(); - } - - //let read_guard = c_lock.read().unwrap(); - //af_print!("C after threads joined", *read_guard); - //C after threads joined - //[3 3 1 1] - // 8.0000 8.0000 8.0000 - // 8.0000 8.0000 8.0000 - // 8.0000 8.0000 8.0000 - // ANCHOR_END: access_using_rwlock - } - - #[test] - fn accum_using_channel() { - // ANCHOR: accum_using_channel - let ops: Vec<_> = vec![Op::Add, Op::Sub, Op::Div, Op::Mul, Op::Add, Op::Div]; - let ops_len: usize = ops.len(); - - // Set active GPU/device on main thread on which - // subsequent Array objects are created - set_device(0); - - let mut c = constant(0.0f32, dim4!(3, 3)); - let a = constant(1.0f32, dim4!(3, 3)); - let b = constant(2.0f32, dim4!(3, 3)); - - let (tx, rx) = mpsc::channel(); - - let threads: Vec<_> = ops - .into_iter() - .map(|op| { - // a and b are internally reference counted by ArrayFire. Unless there - // is prior known need that they may be modified, you can simply clone - // the objects pass them to threads - let x = a.clone(); - let y = b.clone(); - - let tx_clone = tx.clone(); - - thread::spawn(move || { - //Both of objects are created on device 0 in main thread - //Every thread needs to set the device that it is going to - //work on. Note that all Array objects must have been created - //on same device as of date this is written on. - set_device(0); - - let c = match op { - Op::Add => x + y, - Op::Sub => x - y, - Op::Div => x / y, - Op::Mul => x * y, - }; - tx_clone.send(c).unwrap(); - }) - }) - .collect(); - - for _i in 0..ops_len { - c += rx.recv().unwrap(); - } - - //Need to join other threads as main thread holds arrayfire context - for child in threads { - let _ = child.join(); - } - - //af_print!("C after accumulating results", &c); - //[3 3 1 1] - // 8.0000 8.0000 8.0000 - // 8.0000 8.0000 8.0000 - // 8.0000 8.0000 8.0000 - // ANCHOR_END: accum_using_channel - } - - #[cfg(feature = "afserde")] - mod serde_tests { - use super::super::Array; - use crate::algorithm::sum_all; - use crate::randu; - - #[test] - fn array_serde_json() { - // ANCHOR: array_json_serde_snippet - let input = randu!(u8; 2, 2); - let serd = match serde_json::to_string(&input) { - Ok(serialized_str) => serialized_str, - Err(e) => e.to_string(), - }; - - let deserd: Array = serde_json::from_str(&serd).unwrap(); - // ANCHOR_END: array_json_serde_snippet - - assert_eq!(sum_all(&(input - deserd)), (0u32, 0u32)); - } - - #[test] - fn array_serde_bincode() { - // ANCHOR: array_bincode_serde_snippet - let input = randu!(u8; 2, 2); - let encoded = match bincode::serialize(&input) { - Ok(encoded) => encoded, - Err(_) => vec![], - }; - - let decoded: Array = bincode::deserialize(&encoded).unwrap(); - // ANCHOR_END: array_bincode_serde_snippet - - assert_eq!(sum_all(&(input - decoded)), (0u32, 0u32)); - } - } -} diff --git a/src/core/backend.rs b/src/core/backend.rs deleted file mode 100644 index 2cc3749f4..000000000 --- a/src/core/backend.rs +++ /dev/null @@ -1,63 +0,0 @@ -use super::defines::{AfError, Backend}; -use super::error::HANDLE_ERROR; - -use libc::{c_int, c_uint}; - -extern "C" { - fn af_set_backend(bknd: u8) -> c_int; - fn af_get_backend_count(num_backends: *mut c_uint) -> c_int; - fn af_get_available_backends(backends: *mut c_int) -> c_int; - fn af_get_active_backend(backend: *mut c_int) -> c_int; -} - -/// Toggle backends between cuda, opencl or cpu -/// -/// # Parameters -/// -/// - `backend` to which to switch to -pub fn set_backend(backend: Backend) { - let err_val = unsafe { af_set_backend(backend as u8) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get the available backend count -pub fn get_backend_count() -> u32 { - let mut temp: u32 = 0; - let err_val = unsafe { af_get_backend_count(&mut temp as *mut c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp -} - -/// Get the available backends -pub fn get_available_backends() -> Vec { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_available_backends(&mut temp as *mut c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - - let mut b = Vec::new(); - if temp & 0b0100 == 0b0100 { - b.push(Backend::OPENCL); - } - if temp & 0b0010 == 0b0010 { - b.push(Backend::CUDA); - } - if temp & 0b0001 == 0b0001 { - b.push(Backend::CPU); - } - - b -} - -/// Get current active backend -pub fn get_active_backend() -> Backend { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_active_backend(&mut temp as *mut c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - match (err_val, temp) { - (0, 0) => Backend::DEFAULT, - (0, 1) => Backend::CPU, - (0, 2) => Backend::CUDA, - (0, 4) => Backend::OPENCL, - _ => panic!("Invalid backend retrieved, undefined behavior."), - } -} diff --git a/src/core/data.rs b/src/core/data.rs deleted file mode 100644 index 75308807d..000000000 --- a/src/core/data.rs +++ /dev/null @@ -1,988 +0,0 @@ -use super::array::Array; -use super::defines::{AfError, BorderType}; -use super::dim4::Dim4; -use super::error::HANDLE_ERROR; -use super::util::{af_array, c32, c64, dim_t, u64_t, HasAfEnum}; - -use half::f16; -use libc::{c_double, c_int, c_uint}; -use std::option::Option; -use std::vec::Vec; - -extern "C" { - fn af_constant( - out: *mut af_array, - val: c_double, - ndims: c_uint, - dims: *const dim_t, - afdtype: c_uint, - ) -> c_int; - - fn af_constant_complex( - out: *mut af_array, - real: c_double, - imag: c_double, - ndims: c_uint, - dims: *const dim_t, - afdtype: c_uint, - ) -> c_int; - - fn af_constant_long(out: *mut af_array, val: dim_t, ndims: c_uint, dims: *const dim_t) - -> c_int; - - fn af_constant_ulong( - out: *mut af_array, - val: u64_t, - ndims: c_uint, - dims: *const dim_t, - ) -> c_int; - - fn af_range( - out: *mut af_array, - ndims: c_uint, - dims: *const dim_t, - seq_dim: c_int, - afdtype: c_uint, - ) -> c_int; - - fn af_iota( - out: *mut af_array, - ndims: c_uint, - dims: *const dim_t, - t_ndims: c_uint, - tdims: *const dim_t, - afdtype: c_uint, - ) -> c_int; - - fn af_identity(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint) - -> c_int; - fn af_diag_create(out: *mut af_array, arr: af_array, num: c_int) -> c_int; - fn af_diag_extract(out: *mut af_array, arr: af_array, num: c_int) -> c_int; - fn af_join(out: *mut af_array, dim: c_int, first: af_array, second: af_array) -> c_int; - fn af_join_many( - out: *mut af_array, - dim: c_int, - n_arrays: c_uint, - inpts: *const af_array, - ) -> c_int; - - fn af_tile( - out: *mut af_array, - arr: af_array, - x: c_uint, - y: c_uint, - z: c_uint, - w: c_uint, - ) -> c_int; - fn af_reorder( - o: *mut af_array, - a: af_array, - x: c_uint, - y: c_uint, - z: c_uint, - w: c_uint, - ) -> c_int; - fn af_shift(o: *mut af_array, a: af_array, x: c_int, y: c_int, z: c_int, w: c_int) -> c_int; - fn af_moddims(out: *mut af_array, arr: af_array, ndims: c_uint, dims: *const dim_t) -> c_int; - - fn af_flat(out: *mut af_array, arr: af_array) -> c_int; - fn af_flip(out: *mut af_array, arr: af_array, dim: c_uint) -> c_int; - fn af_lower(out: *mut af_array, arr: af_array, is_unit_diag: bool) -> c_int; - fn af_upper(out: *mut af_array, arr: af_array, is_unit_diag: bool) -> c_int; - - fn af_select(out: *mut af_array, cond: af_array, a: af_array, b: af_array) -> c_int; - fn af_select_scalar_l(out: *mut af_array, cond: af_array, a: c_double, b: af_array) -> c_int; - fn af_select_scalar_r(out: *mut af_array, cond: af_array, a: af_array, b: c_double) -> c_int; - - fn af_replace(a: *mut af_array, cond: af_array, b: af_array) -> c_int; - fn af_replace_scalar(a: *mut af_array, cond: af_array, b: c_double) -> c_int; - - fn af_pad( - out: *mut af_array, - input: af_array, - begin_ndims: c_uint, - begin_dims: *const dim_t, - end_ndims: c_uint, - end_dims: *const dim_t, - pad_fill_type: c_uint, - ) -> c_int; -} - -/// Type Trait to generate a constant [Array](./struct.Array.html) of given size -/// -/// Internally, ConstGenerator trait is implemented by following types. -/// -/// - f32 -/// - f64 -/// - num::Complex\ -/// - num::Complex\ -/// - bool -/// - i32 -/// - u32 -/// - u8 -/// - i64 -/// - u64 -/// - i16 -/// - u16 -/// -pub trait ConstGenerator: HasAfEnum { - /// The type of Array object returned by generate function - type OutType: HasAfEnum; - - /// Create an Array of `dims` size from scalar value `self`. - /// - /// # Parameters - /// - /// - `dims` are the dimensions of the output constant [Array](./struct.Array.html) - fn generate(&self, dims: Dim4) -> Array; -} - -impl ConstGenerator for i64 { - type OutType = i64; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant_long( - &mut temp as *mut af_array, - *self, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -impl ConstGenerator for u64 { - type OutType = u64; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant_ulong( - &mut temp as *mut af_array, - *self, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -impl ConstGenerator for c32 { - type OutType = c32; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant_complex( - &mut temp as *mut af_array, - (*self).re as c_double, - (*self).im as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - 1, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -impl ConstGenerator for c64 { - type OutType = c64; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant_complex( - &mut temp as *mut af_array, - (*self).re as c_double, - (*self).im as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - 3, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -impl ConstGenerator for bool { - type OutType = bool; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant( - &mut temp as *mut af_array, - *self as c_int as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - 4, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } -} - -impl ConstGenerator for f16 { - type OutType = f16; - - fn generate(&self, dims: Dim4) -> Array { - unsafe { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = af_constant( - &mut temp as *mut af_array, - f16::to_f64(*self), - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - 12, - ); - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - } -} - -macro_rules! cnst { - ($rust_type:ty, $ffi_type:expr) => { - impl ConstGenerator for $rust_type { - type OutType = $rust_type; - - fn generate(&self, dims: Dim4) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_constant( - &mut temp as *mut af_array, - *self as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - $ffi_type, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - } - }; -} - -cnst!(f32, 0); -cnst!(f64, 2); -cnst!(i32, 5); -cnst!(u32, 6); -cnst!(u8, 7); -cnst!(i16, 10); -cnst!(u16, 11); - -/// Create an Array with constant value -/// -/// The trait ConstGenerator has been defined internally for the following types: -/// -/// - i64 -/// - u64 -/// - num::Complex\ a.k.a c32 -/// - num::Complex\ a.k.a c64 -/// - f32 -/// - f64 -/// - i32 -/// - u32 -/// - u8 -/// - i16 -/// - u16 -/// -/// # Parameters -/// -/// - `cnst` is the constant value to be filled in the Array -/// - `dims` is the size of the constant Array -/// -/// # Return Values -/// -/// An Array of given dimensions with constant value -pub fn constant(cnst: T, dims: Dim4) -> Array -where - T: ConstGenerator, -{ - cnst.generate(dims) -} - -/// Create a Range of values -/// -/// Creates an array with [0, n] values along the `seq_dim` which is tiled across other dimensions. -/// -/// # Parameters -/// -/// - `dims` is the size of Array -/// - `seq_dim` is the dimension along which range values are populated, all values along other -/// dimensions are just repeated -/// -/// # Return Values -/// Array -pub fn range(dims: Dim4, seq_dim: i32) -> Array { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_range( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - seq_dim as c_int, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create a range of values -/// -/// Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims. -/// -/// # Parameters -/// -/// - `dims` is the dimensions of the sequence to be generated -/// - `tdims` is the number of repitions of the unit dimensions -/// -/// # Return Values -/// -/// Array -pub fn iota(dims: Dim4, tdims: Dim4) -> Array { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_iota( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - tdims.ndims() as c_uint, - tdims.get().as_ptr() as *const dim_t, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create an identity array with 1's in diagonal -/// -/// # Parameters -/// -/// - `dims` is the output Array dimensions -/// -/// # Return Values -/// -/// Identity matrix -pub fn identity(dims: Dim4) -> Array { - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_identity( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - aftype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create a diagonal matrix -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `dim` is the diagonal index relative to principal diagonal where values from input Array are -/// to be placed -/// -/// # Return Values -/// -/// An Array with values as a diagonal Matrix -pub fn diag_create(input: &Array, dim: i32) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_diag_create(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Extract diagonal from a given Matrix -/// -/// # Parameters -/// -/// - `input` is the input Matrix -/// - `dim` is the index of the diagonal that has to be extracted from the input Matrix -/// -/// # Return Values -/// -/// An Array with values of the diagonal from input Array -pub fn diag_extract(input: &Array, dim: i32) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_diag_extract(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Join two arrays -/// -/// # Parameters -/// -/// - `dim` is the dimension along which the concatenation has to be done -/// - `first` is the Array that comes first in the concatenation -/// - `second` is the Array that comes last in the concatenation -/// -/// # Return Values -/// -/// Concatenated Array -pub fn join(dim: i32, first: &Array, second: &Array) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_join(&mut temp as *mut af_array, dim, first.get(), second.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Join multiple arrays -/// -/// # Parameters -/// -/// - `dim` is the dimension along which the concatenation has to be done -/// - `inputs` is the vector of Arrays that has to be concatenated -/// -/// # Return Values -/// -/// Concatenated Array -pub fn join_many(dim: i32, inputs: Vec<&Array>) -> Array -where - T: HasAfEnum, -{ - let mut v = Vec::new(); - for i in inputs { - v.push(unsafe { i.get() }); - } - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_join_many( - &mut temp as *mut af_array, - dim, - v.len() as u32, - v.as_ptr() as *const af_array, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Tile the input array along specified dimension -/// -/// Tile essentially creates copies of data along each dimension. -/// The number of copies created is provided by the user on per -/// axis basis using [Dim4](./struct.dim4.html) -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `dims` is the target(output) dimensions -/// -///# Return Values -/// -/// Tiled input array as per the tiling dimensions provided -pub fn tile(input: &Array, dims: Dim4) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_tile( - &mut temp as *mut af_array, - input.get() as af_array, - dims[0] as c_uint, - dims[1] as c_uint, - dims[2] as c_uint, - dims[3] as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Reorder the array according to the new specified axes -/// -/// Exchanges data within an array such that the requested change in axes is -/// satisfied. The linear ordering of data within the array is preserved. -/// -/// The default order of axes in ArrayFire is [0 1 2 3] i.e. axis with smallest -/// distance between adjacent elements followed by next smallest distance axis and -/// so on. See [examples](#examples) to have a basic idea of how data is re-ordered. -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `new_axis0` is the new first axis for output -/// - `new_axis1` is the new second axis for output -/// - `next_axes` is the new axes order for output -/// -///# Return Values -/// -/// Array with data reordered as per the new axes order -/// -///# Examples -/// -/// ```rust -/// use arrayfire::{Array, Dim4, print, randu, reorder_v2}; -/// let a = randu::(Dim4::new(&[5, 3, 1, 1])); -/// let b = reorder_v2(&a, 1, 0, None); -/// print(&a); -/// -/// // [5 3 1 1] -/// // 0.8104 0.2990 0.3014 -/// // 0.6913 0.2802 0.6938 -/// // 0.7821 0.1480 0.3513 -/// // 0.3054 0.1330 0.7176 -/// // 0.1673 0.4696 0.1181 -/// -/// print(&b); -/// // [3 5 1 1] -/// // 0.8104 0.6913 0.7821 0.3054 0.1673 -/// // 0.2990 0.2802 0.1480 0.1330 0.4696 -/// // 0.3014 0.6938 0.3513 0.7176 0.1181 -/// -/// let c = reorder_v2(&a, 2, 0, Some(vec![1])); -/// print(&c); -/// -/// // [1 5 3 1] -/// // 0.8104 0.6913 0.7821 0.3054 0.1673 -/// // -/// // 0.2990 0.2802 0.1480 0.1330 0.4696 -/// // -/// // 0.3014 0.6938 0.3513 0.7176 0.1181 -/// ``` -pub fn reorder_v2( - input: &Array, - new_axis0: u64, - new_axis1: u64, - next_axes: Option>, -) -> Array -where - T: HasAfEnum, -{ - let mut new_axes = [0, 1, 2, 3]; - new_axes[0] = new_axis0; - new_axes[1] = new_axis1; - match next_axes { - Some(left_over_new_axes) => { - // At the moment of writing this comment, ArrayFire could - // handle only a maximum of 4 dimensions. Hence, excluding - // the two explicit axes arguments to this function, a maximum - // of only two more axes can be provided. Hence the below condition. - assert!(left_over_new_axes.len() <= 2); - - new_axes[2..(left_over_new_axes.len() + 2)].clone_from_slice(&left_over_new_axes[..]); - } - None => { - let left_over_indices: Vec = (2..4).collect(); - for a_idx in left_over_indices { - new_axes[a_idx] = a_idx as u64; - } - } - }; - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_reorder( - &mut temp as *mut af_array, - input.get() as af_array, - new_axes[0] as c_uint, - new_axes[1] as c_uint, - new_axes[2] as c_uint, - new_axes[3] as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Reorder the array in specified order -/// -/// The default order of axes in ArrayFire is axis with smallest distance -/// between adjacent elements towards an axis with highest distance between -/// adjacent elements. -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `dims` is the target(output) dimensions -/// -///# Return Values -/// -/// Array with data reordered as per the new axes order -#[deprecated(since = "3.6.3", note = "Please use new reorder API")] -pub fn reorder(input: &Array, dims: Dim4) -> Array -where - T: HasAfEnum, -{ - reorder_v2(input, dims[0], dims[1], Some(vec![dims[2], dims[3]])) -} - -///"Circular shift of values along specified dimension -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `offsets` is 4-value tuple that specifies the shift along respective dimension -/// -///# Return Values -/// -/// An Array with shifted data. -/// -///# Examples -/// -/// ```rust -/// use arrayfire::{Array, Dim4, print, randu, shift}; -/// let a = randu::(Dim4::new(&[5, 1, 1, 1])); -/// let _a = shift(&a, &[-1i32, 1 , 1, 1]); //shift data one step backward -/// let a_ = shift(&a, &[ 1i32, 1 , 1, 1]); //shift data one step forward -/// print(& a); -/// print(&_a); -/// print(&a_); -/// ``` -pub fn shift(input: &Array, offsets: &[i32; 4]) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_shift( - &mut temp as *mut af_array, - input.get(), - offsets[0], - offsets[1], - offsets[2], - offsets[3], - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Change the shape of the Array -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `dims` is the new dimensions to which the input Array is reshaped to -/// -/// # Return Values -/// Reshaped Array -pub fn moddims(input: &Array, dims: Dim4) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_moddims( - &mut temp as *mut af_array, - input.get(), - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Flatten the multidimensional Array to an 1D Array -pub fn flat(input: &Array) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_flat(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Flip the Array -/// -/// # Parameters -/// -/// - `input` is the Array to be flipped -/// - `dim` is the dimension along which the flip has to happen -/// -/// # Return Values -/// -/// Flipped Array -pub fn flip(input: &Array, dim: u32) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_flip(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create lower triangular matrix -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `is_unit_diag` dictates if the output Array should have 1's along diagonal -/// -/// # Return Values -/// Array -pub fn lower(input: &Array, is_unit_diag: bool) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_lower(&mut temp as *mut af_array, input.get(), is_unit_diag) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create upper triangular matrix -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `is_unit_diag` dictates if the output Array should have 1's along diagonal -/// -/// # Return Values -/// Array -pub fn upper(input: &Array, is_unit_diag: bool) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_upper(&mut temp as *mut af_array, input.get(), is_unit_diag) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Element wise conditional operator for Arrays -/// -/// This function does the C-equivalent of the following statement, except that the operation -/// happens on a GPU for all elements simultaneously. -/// -/// ```text -/// c = cond ? a : b; /// where cond, a & b are all objects of type Array -/// ``` -/// -/// # Parameters -/// -/// - `a` is the Array whose element will be assigned to output if corresponding element in `cond` Array is -/// `True` -/// - `cond` is the Array with boolean values -/// - `b` is the Array whose element will be assigned to output if corresponding element in `cond` Array is -/// `False` -/// -/// # Return Values -/// -/// An Array -pub fn select(a: &Array, cond: &Array, b: &Array) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_select(&mut temp as *mut af_array, cond.get(), a.get(), b.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Element wise conditional operator for Arrays -/// -/// This function does the C-equivalent of the following statement, except that the operation -/// happens on a GPU for all elements simultaneously. -/// -/// ```text -/// c = cond ? a : b; /// where a is a scalar(f64) and b is Array -/// ``` -/// -/// # Parameters -/// -/// - `a` is the scalar that is assigned to output if corresponding element in `cond` Array is -/// `True` -/// - `cond` is the Array with conditional values -/// - `b` is the Array whose element will be assigned to output if corresponding element in `cond` Array is -/// `False` -/// -/// # Return Values -/// -/// An Array -pub fn selectl(a: f64, cond: &Array, b: &Array) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_select_scalar_l(&mut temp as *mut af_array, cond.get(), a, b.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Element wise conditional operator for Arrays -/// -/// This function does the C-equivalent of the following statement, except that the operation -/// happens on a GPU for all elements simultaneously. -/// -/// ```text -/// c = cond ? a : b; /// where a is Array and b is a scalar(f64) -/// ``` -/// -/// # Parameters -/// -/// - `a` is the Array whose element will be assigned to output if corresponding element in `cond` Array is -/// `True` -/// - `cond` is the Array with conditional values -/// - `b` is the scalar that is assigned to output if corresponding element in `cond` Array is -/// `False` -/// -/// # Return Values -/// -/// An Array -pub fn selectr(a: &Array, cond: &Array, b: f64) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_select_scalar_r(&mut temp as *mut af_array, cond.get(), a.get(), b) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inplace replace in Array based on a condition -/// -/// This function does the C-equivalent of the following statement, except that the operation -/// happens on a GPU for all elements simultaneously. -/// -/// ```text -/// a = cond ? a : b; /// where cond, a & b are all objects of type Array -/// ``` -/// -/// # Parameters -/// -/// - `a` is the Array whose element will be replaced with element from `b` if corresponding element in `cond` Array is `True` -/// - `cond` is the Array with conditional values -/// - `b` is the Array whose element will replace the element in output if corresponding element in `cond` Array is -/// `False` -/// -/// # Return Values -/// -/// None -pub fn replace(a: &mut Array, cond: &Array, b: &Array) -where - T: HasAfEnum, -{ - let err_val = unsafe { af_replace(a.get() as *mut af_array, cond.get(), b.get()) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Inplace replace in Array based on a condition -/// -/// This function does the C-equivalent of the following statement, except that the operation -/// happens on a GPU for all elements simultaneously. -/// -/// ```text -/// a = cond ? a : b; /// where cond, a are Arrays and b is scalar(f64) -/// ``` -/// -/// # Parameters -/// -/// - `a` is the Array whose element will be replaced with element from `b` if corresponding element in `cond` Array is `True` -/// - `cond` is the Array with conditional values -/// - `b` is the scalar that will replace the element in output if corresponding element in `cond` Array is -/// `False` -/// -/// # Return Values -/// -/// None -pub fn replace_scalar(a: &mut Array, cond: &Array, b: f64) -where - T: HasAfEnum, -{ - let err_val = unsafe { af_replace_scalar(a.get() as *mut af_array, cond.get(), b) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Pad input Array along borders -/// -/// # Parameters -/// -/// - `input` is the input array to be padded -/// - `begin` is padding size before first element along a given dimension -/// - `end` is padding size after the last element along a given dimension -/// - `fill_type` indicates what values should be used to fill padded regions -/// -/// # Return Values -/// -/// Padded Array -pub fn pad( - input: &Array, - begin: Dim4, - end: Dim4, - fill_type: BorderType, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_pad( - &mut temp as *mut af_array, - input.get(), - 4, - begin.get().as_ptr() as *const dim_t, - 4, - end.get().as_ptr() as *const dim_t, - fill_type as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -#[cfg(test)] -mod tests { - use super::reorder_v2; - - use super::super::defines::BorderType; - use super::super::device::set_device; - use super::super::random::randu; - use super::pad; - - use crate::dim4; - - #[test] - fn check_reorder_api() { - set_device(0); - let a = randu::(dim4!(4, 5, 2, 3)); - - let _transposed = reorder_v2(&a, 1, 0, None); - let _swap_0_2 = reorder_v2(&a, 2, 1, Some(vec![0])); - let _swap_1_2 = reorder_v2(&a, 0, 2, Some(vec![1])); - let _swap_0_3 = reorder_v2(&a, 3, 1, Some(vec![2, 0])); - } - - #[test] - fn check_pad_api() { - set_device(0); - let a = randu::(dim4![3, 3]); - let begin_dims = dim4!(0, 0, 0, 0); - let end_dims = dim4!(2, 2, 0, 0); - let _padded = pad(&a, begin_dims, end_dims, BorderType::ZERO); - } -} diff --git a/src/core/defines.rs b/src/core/defines.rs deleted file mode 100644 index b11662793..000000000 --- a/src/core/defines.rs +++ /dev/null @@ -1,640 +0,0 @@ -use num::Complex; -use std::fmt::Error as FmtError; -use std::fmt::{Display, Formatter}; - -#[cfg(feature = "afserde")] -use serde::{Deserialize, Serialize}; - -/// Error codes -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum AfError { - /// The function returned successfully - SUCCESS = 0, - // 100-199 Errors in environment - /// The system or device ran out of memory - ERR_NO_MEM = 101, - /// There was an error in the device driver - ERR_DRIVER = 102, - /// There was an error with the runtime environment - ERR_RUNTIME = 103, - // 200-299 Errors in input parameters - /// The input array is not a valid Array object - ERR_INVALID_ARRAY = 201, - /// One of the function arguments is incorrect - ERR_ARG = 202, - /// The size is incorrect - ERR_SIZE = 203, - /// The type is not suppported by this function - ERR_TYPE = 204, - /// The type of the input arrays are not compatible - ERR_DIFF_TYPE = 205, - /// Function does not support GFOR / batch mode - ERR_BATCH = 207, - /// Input does not belong to the current device - ERR_DEVICE = 208, - // 300-399 Errors for missing software features - /// The option is not supported - ERR_NOT_SUPPORTED = 301, - /// This build of ArrayFire does not support this feature - ERR_NOT_CONFIGURED = 302, - // 400-499 Errors for missing hardware features - /// This device does not support double - ERR_NO_DBL = 401, - /// This build of ArrayFire was not built with graphics or this device does - /// not support graphics - ERR_NO_GFX = 402, - // 900-999 Errors from upstream libraries and runtimes - /// There was an internal error either in ArrayFire or in a project - /// upstream - ERR_INTERNAL = 998, - /// Unknown Error - ERR_UNKNOWN = 999, -} - -/// Compute/Acceleration Backend -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum Backend { - /// Default backend order: CUDA -> OpenCL -> CPU - DEFAULT = 0, - /// CPU a.k.a sequential algorithms - CPU = 1, - /// CUDA Compute Backend - CUDA = 2, - /// OpenCL Compute Backend - OPENCL = 4, -} - -impl Display for Backend { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - let text = match *self { - Backend::OPENCL => "OpenCL", - Backend::CUDA => "Cuda", - Backend::CPU => "CPU", - Backend::DEFAULT => "Default", - }; - write!(f, "{}", text) - } -} - -impl Display for AfError { - fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - let text = match *self { - AfError::SUCCESS => "Function returned successfully", - AfError::ERR_NO_MEM => "System or Device ran out of memory", - AfError::ERR_DRIVER => "Error in the device driver", - AfError::ERR_RUNTIME => "Error with the runtime environment", - AfError::ERR_INVALID_ARRAY => "Iput Array is not a valid object", - AfError::ERR_ARG => "One of the function arguments is incorrect", - AfError::ERR_SIZE => "Size is incorrect", - AfError::ERR_TYPE => "Type is not suppported by this function", - AfError::ERR_DIFF_TYPE => "Type of the input arrays are not compatible", - AfError::ERR_BATCH => "Function does not support GFOR / batch mode", - AfError::ERR_DEVICE => "Input does not belong to the current device", - AfError::ERR_NOT_SUPPORTED => "Unsupported operation/parameter option", - AfError::ERR_NOT_CONFIGURED => "This build of ArrayFire does not support this feature", - AfError::ERR_NO_DBL => "This device does not support double", - AfError::ERR_NO_GFX => "This build of ArrayFire has no graphics support", - AfError::ERR_INTERNAL => "Error either in ArrayFire or in a project upstream", - AfError::ERR_UNKNOWN => "Unknown Error", - }; - write!(f, "{}", text) - } -} - -/// Types of Array data type -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum DType { - /// 32 bit float - F32 = 0, - /// 32 bit complex float - C32 = 1, - /// 64 bit float - F64 = 2, - /// 64 bit complex float - C64 = 3, - /// 8 bit boolean - B8 = 4, - /// 32 bit signed integer - S32 = 5, - /// 32 bit unsigned integer - U32 = 6, - /// 8 bit unsigned integer - U8 = 7, - /// 64 bit signed integer - S64 = 8, - /// 64 bit unsigned integer - U64 = 9, - /// 16 bit signed integer - S16 = 10, - /// 16 bit unsigned integer - U16 = 11, - /// 16 bit floating point - F16 = 12, -} - -/// Dictates the interpolation method to be used by a function -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum InterpType { - /// Nearest Neighbor interpolation method - NEAREST = 0, - /// Linear interpolation method - LINEAR = 1, - /// Bilinear interpolation method - BILINEAR = 2, - /// Cubic interpolation method - CUBIC = 3, - /// Floor indexed - LOWER = 4, - /// Linear interpolation with cosine smoothing - LINEAR_COSINE = 5, - /// Bilinear interpolation with cosine smoothing - BILINEAR_COSINE = 6, - /// Bicubic interpolation - BICUBIC = 7, - /// Cubic interpolation with Catmull-Rom splines - CUBIC_SPLINE = 8, - /// Bicubic interpolation with Catmull-Rom splines - BICUBIC_SPLINE = 9, -} - -/// Helps determine how to pad kernels along borders -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum BorderType { - /// Pad using zeros - ZERO = 0, - /// Pad using mirrored values along border - SYMMETRIC = 1, - - /// Out of bound values are clamped to the edge - CLAMP_TO_EDGE, - - /// Out of bound values are mapped to range of the dimension in cyclic fashion - PERIODIC, -} - -/// Used by `regions` function to identify type of connectivity -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum Connectivity { - /// North-East-South-West (N-E-S-W) connectivity from given pixel/point - FOUR = 4, - /// N-NE-E-SE-S-SW-W-NW connectivity from given pixel/point - EIGHT = 8, -} - -/// Helps determine the size of output of convolution -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum ConvMode { - /// Default convolution mode where output size is same as input size - DEFAULT = 0, - /// Output of convolution is expanded based on signal and filter sizes - EXPAND = 1, -} - -/// Helps determine if convolution is in Spatial or Frequency domain -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum ConvDomain { - /// ArrayFire chooses whether the convolution will be in spatial domain or frequency domain - AUTO = 0, - /// Convoltion in spatial domain - SPATIAL = 1, - /// Convolution in frequency domain - FREQUENCY = 2, -} - -/// Error metric used by `matchTemplate` function -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum MatchType { - /// Sum of Absolute Differences - SAD = 0, - /// Zero-mean Sum of Absolute Differences - ZSAD = 1, - /// Locally scaled Sum of Absolute Differences - LSAD = 2, - /// Sum of Squared Differences - SSD = 3, - /// Zero-mean Sum of Squared Differences - ZSSD = 4, - /// Localy scaled Sum of Squared Differences - LSSD = 5, - /// Normalized Cross Correlation - NCC = 6, - /// Zero-mean Normalized Cross Correlation - ZNCC = 7, - /// Sum of Hamming Distances - SHD = 8, -} - -/// Identify the color space of given image(Array) -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum ColorSpace { - /// Grayscale color space - GRAY = 0, - /// Red-Green-Blue color space - RGB = 1, - /// Hue-Saturation-value color space - HSV = 2, -} - -/// Helps determine the type of a Matrix -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum MatProp { - /// Default (no-op) - NONE = 0, - /// Data needs to be transposed - TRANS = 1, - /// Data needs to be conjugate transposed - CTRANS = 2, - /// Matrix is upper triangular - CONJ = 4, - /// Matrix needs to be conjugate - UPPER = 32, - /// Matrix is lower triangular - LOWER = 64, - /// Matrix diagonal has unitary values - DIAGUNIT = 128, - /// Matrix is symmetric - SYM = 512, - /// Matrix is positive definite - POSDEF = 1024, - /// Matrix is orthogonal - ORTHOG = 2048, - /// Matrix is tri-diagonal - TRIDIAG = 4096, - /// Matrix is block-diagonal - BLOCKDIAG = 8192, -} - -/// Norm type -#[allow(non_camel_case_types)] -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum NormType { - /// Treats input as a vector and return sum of absolute values - VECTOR_1 = 0, - /// Treats input as vector and return max of absolute values - VECTOR_INF = 1, - /// Treats input as vector and returns euclidean norm - VECTOR_2 = 2, - /// Treats input as vector and returns the p-norm - VECTOR_P = 3, - /// Return the max of column sums - MATRIX_1 = 4, - /// Return the max of row sums - MATRIX_INF = 5, - /// Returns the max singular value (Currently not supported) - MATRIX_2 = 6, - /// Returns Lpq-norm - MATRIX_L_PQ = 7, -} - -/// Dictates what color map is used for Image rendering -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum ColorMap { - /// Default color map is grayscale range [0-1] - DEFAULT = 0, - /// Visible spectrum color map - SPECTRUM = 1, - /// Colors - COLORS = 2, - /// Red hue map - RED = 3, - /// Mood color map - MOOD = 4, - /// Heat color map - HEAT = 5, - /// Blue hue map - BLUE = 6, -} - -/// YCbCr Standards -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum YCCStd { - /// ITU-R BT.601 (formerly CCIR 601) standard - YCC_601 = 601, - /// ITU-R BT.709 standard - YCC_709 = 709, - /// ITU-R BT.2020 standard - YCC_2020 = 2020, -} - -/// Homography type -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum HomographyType { - /// RANdom SAmple Consensus algorithm - RANSAC = 0, - /// Least Median of Squares - LMEDS = 1, -} - -/// Plotting markers -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum MarkerType { - /// No marker - NONE = 0, - /// Pointer marker - POINT = 1, - /// Hollow circle marker - CIRCLE = 2, - /// Hollow Square marker - SQUARE = 3, - /// Hollow Triangle marker - TRIANGLE = 4, - /// Cross-hair marker - CROSS = 5, - /// Plus symbol marker - PLUS = 6, - /// Start symbol marker - STAR = 7, -} - -/// Image moment types -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum MomentType { - /// Central moment of order (0 + 0) - M00 = 1, // 1<<0 - /// Central moment of order (0 + 1) - M01 = 2, // 1<<1 - /// Central moment of order (1 + 0) - M10 = 4, // 1<<2 - /// Central moment of order (1 + 1) - M11 = 8, // 1<<3 - /// All central moments of order (0,0), (0,1), (1,0) and (1,1) - FIRST_ORDER = 1 | 1 << 1 | 1 << 2 | 1 << 3, -} - -/// Sparse storage format type -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum SparseFormat { - /// Dense format - DENSE = 0, - /// Compressed sparse row format - CSR = 1, - /// Compressed sparse coloumn format - CSC = 2, - /// Coordinate list (row, coloumn, value) tuples. - COO = 3, -} - -/// Binary operation types for generalized scan functions -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum BinaryOp { - /// Addition operation - ADD = 0, - /// Multiplication operation - MUL = 1, - /// Minimum operation - MIN = 2, - /// Maximum operation - MAX = 3, -} - -/// Random engine types -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum RandomEngineType { - ///Philox variant with N=4, W=32 and Rounds=10 - PHILOX_4X32_10 = 100, - ///Threefry variant with N=2, W=32 and Rounds=16 - THREEFRY_2X32_16 = 200, - ///Mersenne variant with MEXP = 11213 - MERSENNE_GP11213 = 300, -} - -/// Default Philon RandomEngine that points to [PHILOX_4X32_10](./enum.RandomEngineType.html) -pub const PHILOX: RandomEngineType = RandomEngineType::PHILOX_4X32_10; -/// Default Threefry RandomEngine that points to [THREEFRY_2X32_16](./enum.RandomEngineType.html) -pub const THREEFRY: RandomEngineType = RandomEngineType::THREEFRY_2X32_16; -/// Default Mersenne RandomEngine that points to [MERSENNE_GP11213](./enum.RandomEngineType.html) -pub const MERSENNE: RandomEngineType = RandomEngineType::MERSENNE_GP11213; -/// Default RandomEngine that defaults to [PHILOX](./constant.PHILOX.html) -pub const DEFAULT_RANDOM_ENGINE: RandomEngineType = PHILOX; - -#[cfg(feature = "afserde")] -#[derive(Serialize, Deserialize)] -#[serde(remote = "Complex")] -struct ComplexDef { - re: T, - im: T, -} - -/// Scalar value types -#[derive(Clone, Copy, Debug, PartialEq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum Scalar { - /// 32 bit float - F32(f32), - /// 32 bit complex float - #[cfg_attr(feature = "afserde", serde(with = "ComplexDef"))] - C32(Complex), - /// 64 bit float - F64(f64), - /// 64 bit complex float - #[cfg_attr(feature = "afserde", serde(with = "ComplexDef"))] - C64(Complex), - /// 8 bit boolean - B8(bool), - /// 32 bit signed integer - S32(i32), - /// 32 bit unsigned integer - U32(u32), - /// 8 bit unsigned integer - U8(u8), - /// 64 bit signed integer - S64(i64), - /// 64 bit unsigned integer - U64(u64), - /// 16 bit signed integer - S16(i16), - /// 16 bit unsigned integer - U16(u16), -} - -/// Canny edge detector threshold operations types -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum CannyThresholdType { - /// User has to define canny thresholds manually - MANUAL = 0, - /// Determine canny algorithm high threshold using Otsu algorithm automatically - OTSU = 1, -} - -/// Anisotropic diffusion flux equation types -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum DiffusionEq { - /// Quadratic flux function - QUADRATIC = 1, - /// Exponential flux function - EXPONENTIAL = 2, - /// Default flux function, a.k.a exponential - DEFAULT = 0, -} - -/// Diffusion equation types -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum FluxFn { - /// Quadratic flux function - GRADIENT = 1, - /// Modified curvature diffusion equation - MCDE = 2, - /// Default diffusion method, Gradient - DEFAULT = 0, -} - -/// topk function ordering -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum TopkFn { - /// Top k min values - MIN = 1, - /// Top k max values - MAX = 2, - /// Default option(max) - DEFAULT = 0, -} - -/// Iterative Deconvolution Algorithm -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum IterativeDeconvAlgo { - /// Land-Weber Algorithm - LANDWEBER = 1, - /// Richardson-Lucy Algorithm - RICHARDSONLUCY = 2, - /// Default is Land-Weber algorithm - DEFAULT = 0, -} - -/// Inverse Deconvolution Algorithm -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum InverseDeconvAlgo { - /// Tikhonov algorithm - TIKHONOV = 1, - /// Default is Tikhonov algorithm - DEFAULT = 0, -} - -/// Gradient mode for convolution -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum ConvGradientType { - /// Filter Gradient - FILTER = 1, - /// Data Gradient - DATA = 2, - /// Biased Gradient - BIAS = 3, - /// Default is Data Gradient - DEFAULT = 0, -} - -/// Gradient mode for convolution -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum VarianceBias { - /// Sample variance - SAMPLE = 1, - /// Population variance - POPULATION = 2, - /// Default (Population) variance - DEFAULT = 0, -} - -/// Gradient mode for convolution -#[repr(u32)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub enum CublasMathMode { - /// To indicate use of Tensor Cores on CUDA capable GPUs - TENSOR_OP = 1, - /// Default i.e. tensor core operations will be avoided by the library - DEFAULT = 0, -} - -#[cfg(test)] -mod tests { - #[cfg(feature = "afserde")] - mod serde_tests { - #[test] - fn test_enum_serde() { - use super::super::AfError; - - let err_code = AfError::ERR_NO_MEM; - let serd = match serde_json::to_string(&err_code) { - Ok(serialized_str) => serialized_str, - Err(e) => e.to_string(), - }; - assert_eq!(serd, "\"ERR_NO_MEM\""); - - let deserd: AfError = serde_json::from_str(&serd).unwrap(); - assert_eq!(deserd, AfError::ERR_NO_MEM); - } - - #[test] - fn test_scalar_serde() { - use super::super::Scalar; - use num::Complex; - - let scalar = Scalar::C32(Complex { - re: 1.0f32, - im: 1.0f32, - }); - let serd = match serde_json::to_string(&scalar) { - Ok(serialized_str) => serialized_str, - Err(e) => e.to_string(), - }; - - let deserd: Scalar = serde_json::from_str(&serd).unwrap(); - assert_eq!(deserd, scalar); - } - } -} diff --git a/src/core/device.rs b/src/core/device.rs deleted file mode 100644 index 6f2f80d53..000000000 --- a/src/core/device.rs +++ /dev/null @@ -1,339 +0,0 @@ -use super::defines::AfError; -use super::error::HANDLE_ERROR; -use super::util::{dim_t, free_host, void_ptr}; - -use libc::{c_char, c_int, size_t}; -use std::borrow::Cow; -use std::ffi::{CStr, CString}; - -extern "C" { - fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int; - fn af_get_revision() -> *const c_char; - fn af_info() -> c_int; - fn af_info_string(str: *mut *mut c_char, verbose: bool) -> c_int; - fn af_device_info( - d_name: *mut c_char, - d_platform: *mut c_char, - d_toolkit: *mut c_char, - d_compute: *mut c_char, - ) -> c_int; - fn af_init() -> c_int; - fn af_get_device_count(nDevices: *mut c_int) -> c_int; - fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int; - fn af_set_device(device: c_int) -> c_int; - fn af_get_device(device: *mut c_int) -> c_int; - fn af_device_mem_info( - alloc_bytes: *mut size_t, - alloc_buffers: *mut size_t, - lock_bytes: *mut size_t, - lock_buffers: *mut size_t, - ) -> c_int; - fn af_print_mem_info(msg: *const c_char, device_id: c_int) -> c_int; - fn af_set_mem_step_size(step_bytes: size_t) -> c_int; - fn af_get_mem_step_size(step_bytes: *mut size_t) -> c_int; - fn af_device_gc() -> c_int; - fn af_sync(device: c_int) -> c_int; - - fn af_alloc_pinned(non_pagable_ptr: *mut void_ptr, bytes: dim_t) -> c_int; - fn af_free_pinned(non_pagable_ptr: void_ptr) -> c_int; - fn af_get_half_support(available: *mut c_int, device: c_int) -> c_int; -} - -/// Get ArrayFire Version Number -/// -/// # Return Values -/// A triplet of integers indicating major, minor & fix release version numbers. -pub fn get_version() -> (i32, i32, i32) { - let mut maj: i32 = 0; - let mut min: i32 = 0; - let mut pat: i32 = 0; - let err_val = unsafe { - af_get_version( - &mut maj as *mut c_int, - &mut min as *mut c_int, - &mut pat as *mut c_int, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (maj, min, pat) -} - -/// Get ArrayFire Revision (commit) information of the library. -/// -/// # Return Values -/// This returns a `Cow<'static, str>` as the string is constructed at compile time. -pub fn get_revision() -> Cow<'static, str> { - unsafe { CStr::from_ptr(af_get_revision()).to_string_lossy() } -} - -/// Print library meta-info -/// -/// # Examples -/// -/// An example output of `af::info` call looks like below -/// -/// ```text -/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38) -/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000 -/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0 -/// ``` -pub fn info() { - let err_val = unsafe { af_info() }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Return library meta-info as `String` -/// -/// # Examples -/// -/// An example output of `af::info_string` call looks like below -/// -/// ```text -/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38) -/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000 -/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0 -/// ``` -pub fn info_string(verbose: bool) -> String { - let mut tmp: *mut c_char = ::std::ptr::null_mut(); - let err_val = unsafe { af_info_string(&mut tmp, verbose) }; - HANDLE_ERROR(AfError::from(err_val)); - let result: String = unsafe { CStr::from_ptr(tmp).to_string_lossy().into_owned() }; - free_host(tmp); - result -} - -/// Gets the information about device and platform as strings. -/// -/// # Return Values -/// A tuple of `String` indicating the name, platform, toolkit and compute. -pub fn device_info() -> (String, String, String, String) { - let mut name: [c_char; 64] = [0; 64]; - let mut platform: [c_char; 10] = [0; 10]; - let mut toolkit: [c_char; 64] = [0; 64]; - let mut compute: [c_char; 10] = [0; 10]; - unsafe { - let err_val = af_device_info( - &mut name[0], - &mut platform[0], - &mut toolkit[0], - &mut compute[0], - ); - HANDLE_ERROR(AfError::from(err_val)); - ( - CStr::from_ptr(name.as_mut_ptr()) - .to_string_lossy() - .into_owned(), - CStr::from_ptr(platform.as_mut_ptr()) - .to_string_lossy() - .into_owned(), - CStr::from_ptr(toolkit.as_mut_ptr()) - .to_string_lossy() - .into_owned(), - CStr::from_ptr(compute.as_mut_ptr()) - .to_string_lossy() - .into_owned(), - ) - } -} - -/// Initialize ArrayFire library -/// -/// 0th device will be the default device unless init call -/// is followed by set_device -pub fn init() { - let err_val = unsafe { af_init() }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get total number of available devices -pub fn device_count() -> i32 { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_device_count(&mut temp as *mut c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - temp -} - -/// Check if a device has double support -/// -/// # Parameters -/// -/// - `device` is the device for which double support is checked for -/// -/// # Return Values -/// -/// `True` if `device` device has double support, `False` otherwise. -pub fn is_double_available(device: i32) -> bool { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_dbl_support(&mut temp as *mut c_int, device as c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - temp > 0 -} - -/// Set active device -/// -/// # Parameters -/// -/// - `device` is the value of the device identifier which has to be set as active -pub fn set_device(device: i32) { - let err_val = unsafe { af_set_device(device as c_int) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get the current active device id -pub fn get_device() -> i32 { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_device(&mut temp as *mut c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - temp -} - -/// Get memory information from the memory manager for the current active device -/// -/// # Parameters -/// -/// This function doesn't take any input parameters -/// -/// # Return Values -/// -/// A quadruple of values regarding the following information. -/// -/// * Number of bytes allocated -/// * Number of buffers allocated -/// * Number of bytes locked -/// * Number of buffers locked -pub fn device_mem_info() -> (usize, usize, usize, usize) { - let mut o0: usize = 0; - let mut o1: usize = 0; - let mut o2: usize = 0; - let mut o3: usize = 0; - let err_val = unsafe { - af_device_mem_info( - &mut o0 as *mut size_t, - &mut o1 as *mut size_t, - &mut o2 as *mut size_t, - &mut o3 as *mut size_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (o0, o1, o2, o3) -} - -/// Print buffer details from the ArrayFire device manager -/// -/// This information is printed in the form of a table. -/// -/// # Parameters -/// -/// - `msg` is a message to print before the table -/// - `device` is the id of the device for which buffer details are to be printed -/// -/// # Return Values -/// -/// None -pub fn print_mem_info(msg: String, device: i32) { - let cmsg = CString::new(msg.as_bytes()); - match cmsg { - Ok(v) => { - let err_val = unsafe { - af_print_mem_info( - v.to_bytes_with_nul().as_ptr() as *const c_char, - device as c_int, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL), - } -} - -/// Set the minimum memory chunk size -/// -/// # Parameters -/// -/// - `step_bytes` is the size of minimum memory chunk in bytes -/// -/// # Return Values -/// -/// None -pub fn set_mem_step_size(step_bytes: usize) { - let err_val = unsafe { af_set_mem_step_size(step_bytes as size_t) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get the minimum memory chunk size -/// -/// # Parameters -/// -/// None -/// -/// # Return Values -/// -/// Returns is the size of minimum memory chunk in bytes -pub fn get_mem_step_size() -> usize { - let mut temp: usize = 0; - let err_val = unsafe { af_get_mem_step_size(&mut temp as *mut size_t) }; - HANDLE_ERROR(AfError::from(err_val)); - temp -} - -/// Call the garbage collection routine -pub fn device_gc() { - let err_val = unsafe { af_device_gc() }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Sync all operations on given device -/// -/// # Parameters -/// -/// - `device` on which the operations are to be synced -/// -/// # Return Values -/// -/// None -pub fn sync(device: i32) { - let err_val = unsafe { af_sync(device as c_int) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Allocate non-pageable memory on HOST memory -/// -/// # Safety -/// -/// Non-pageable memory allocations should be done by users -/// who understand the consequences of such allocations on other -/// tasks running on the system. -pub unsafe fn alloc_pinned(bytes: usize) -> void_ptr { - let mut out: void_ptr = std::ptr::null_mut(); - let err_val = af_alloc_pinned(&mut out as *mut void_ptr, bytes as dim_t); - HANDLE_ERROR(AfError::from(err_val)); - out -} - -/// Free the pointer returned by [alloc_pinned](./fn.alloc_pinned.html) -/// -/// # Safety -/// -/// This function is intended to be called on pointers that were earlier -/// allocated using [alloc_pinned](./fn.alloc_pinned.html). Any other values -/// passed as argument would result in undefined behavior. -pub unsafe fn free_pinned(ptr: void_ptr) { - let err_val = af_free_pinned(ptr); - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Check if a device has half support -/// -/// # Parameters -/// -/// - `device` is the device for which half precision support is checked for -/// -/// # Return Values -/// -/// `True` if `device` device has half support, `False` otherwise. -pub fn is_half_available(device: i32) -> bool { - let mut temp: i32 = 0; - let err_val = unsafe { af_get_half_support(&mut temp as *mut c_int, device as c_int) }; - HANDLE_ERROR(AfError::from(err_val)); - temp > 0 -} diff --git a/src/core/dim4.rs b/src/core/dim4.rs deleted file mode 100644 index 6226edb6e..000000000 --- a/src/core/dim4.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::fmt; -use std::ops::{Index, IndexMut}; - -#[cfg(feature = "afserde")] -use serde::{Deserialize, Serialize}; - -/// Dim4 is used to store [Array](./struct.Array.html) dimensions -#[derive(Copy, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -pub struct Dim4 { - dims: [u64; 4], -} - -/// Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1] -impl Default for Dim4 { - fn default() -> Self { - Self { dims: [1, 1, 1, 1] } - } -} - -/// Enables index operation for Dim4 -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::Dim4; -/// -/// let dims = Dim4::new(&[4, 4, 2, 1]); -/// println!("0th Dimension length is {}", dims[0]); // -> 4 -/// println!("1th Dimension length is {}", dims[1]); // -> 4 -/// println!("2th Dimension length is {}", dims[2]); // -> 2 -/// println!("3th Dimension length is {}", dims[3]); // -> 1 -/// ``` -impl Index for Dim4 { - type Output = u64; - - fn index(&self, _index: usize) -> &u64 { - &self.dims[_index] - } -} - -/// Enables index operation for Dim4 to modify dimensions -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::Dim4; -/// -/// let mut dims = Dim4::new(&[4, 4, 2, 1]); -/// dims[2] = 4; -/// println!("Dimensions: {}", dims); // note that third dimension changed to 4 -/// ``` -impl IndexMut for Dim4 { - fn index_mut(&mut self, _index: usize) -> &mut Self::Output { - &mut self.dims[_index] - } -} - -/// Enables use of Dim4 objects for printing it to display -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::Dim4; -/// -/// let dims = Dim4::new(&[4, 4, 2, 1]); -/// println!("Shape is {}", dims); // -> [4, 4, 2, 1] -/// ``` -impl fmt::Display for Dim4 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "[{}, {}, {}, {}]", - self.dims[0], self.dims[1], self.dims[2], self.dims[3] - ) - } -} - -/// Debug trait implementation for Dim4 objects -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::Dim4; -/// -/// let dims = Dim4::new(&[4, 4, 2, 1]); -/// println!("Shape is {:?}", dims); // -> {4, 4, 2, 1} -/// ``` -impl fmt::Debug for Dim4 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "[{}, {}, {}, {}]", - self.dims[0], self.dims[1], self.dims[2], self.dims[3] - ) - } -} - -impl Dim4 { - /// Create Dim4 object - /// - /// # Examples - /// - /// ```rust - /// use arrayfire::Dim4; - /// let dims = Dim4::new(&[4, 4, 2, 1]); - /// ``` - pub fn new(dims: &[u64; 4]) -> Self { - Self { - dims: [dims[0], dims[1], dims[2], dims[3]], - } - } - - /// Get the number of elements represented by Dim4 object - pub fn elements(&self) -> u64 { - self.dims[0] * self.dims[1] * self.dims[2] * self.dims[3] - } - - /// Get the number of dimensions of Dim4 - pub fn ndims(&self) -> usize { - let nelems = self.elements(); - match nelems { - 0 => 0, - 1 => 1, - _ => { - if self.dims[3] != 1 { - 4 - } else if self.dims[2] != 1 { - 3 - } else if self.dims[1] != 1 { - 2 - } else { - 1 - } - } - } - } - - /// Get the dimensions as a slice of 4 values - pub fn get(&self) -> &[u64; 4] { - &self.dims - } -} - -#[cfg(test)] -mod tests { - #[cfg(feature = "afserde")] - mod serde_tests { - use super::super::Dim4; - use crate::dim4; - - #[test] - fn dim4_serde() { - // ANCHOR: dim4_json_serde_snippet - let dims = dim4!(4, 4); - let serd = match serde_json::to_string(&dims) { - Ok(serialized_str) => serialized_str, - Err(e) => e.to_string(), - }; - assert_eq!(serd, "{\"dims\":[4,4,1,1]}"); - - let deserd: Dim4 = serde_json::from_str(&serd).unwrap(); - assert_eq!(deserd, dims); - // ANCHOR_END: dim4_json_serde_snippet - } - } -} diff --git a/src/core/error.rs b/src/core/error.rs deleted file mode 100644 index d5b8b35bc..000000000 --- a/src/core/error.rs +++ /dev/null @@ -1,111 +0,0 @@ -use super::defines::AfError; -use super::util::{dim_t, free_host}; - -use libc::c_char; -use std::ffi::CStr; -use std::ops::{Deref, DerefMut}; -use std::sync::RwLock; - -extern "C" { - fn af_get_last_error(str: *mut *mut c_char, len: *mut dim_t); -} - -/// Signature of error handling callback function -pub type ErrorCallback = fn(AfError); - -/// Structure holding handle to callback function -pub struct Callback { - cb: ErrorCallback, -} - -impl Callback { - /// Associated function to create a new Callback object - pub fn new(callback: ErrorCallback) -> Self { - Self { cb: callback } - } - - /// call invokes the error callback with `error_code`. - pub fn call(&self, error_code: AfError) { - (self.cb)(error_code) - } -} - -/// Default error handling callback provided by ArrayFire crate -pub fn handle_error_general(error_code: AfError) { - match error_code { - AfError::SUCCESS => {} /* No-op */ - _ => panic!( - "Error message: {}\nLast error: {}", - error_code, - get_last_error() - ), - } -} - -lazy_static! { - static ref ERROR_HANDLER_LOCK: RwLock = - RwLock::new(Callback::new(handle_error_general)); -} - -/// Register user provided error handler -/// -/// # Examples -/// ``` -/// #[macro_use] -/// extern crate arrayfire; -/// -/// use arrayfire::{AfError, Callback, info, register_error_handler}; -/// use std::error::Error; -/// -/// fn handle_error(error_code: AfError) { -/// match error_code { -/// AfError::SUCCESS => {}, /* No-op */ -/// _ => panic!("Error message: {}", error_code), -/// } -/// } -/// -/// fn main() { -/// //Registering the error handler should be the first call -/// //before any other functions are called if your version -/// //of error is to be used for subsequent function calls -/// register_error_handler(Callback::new(handle_error)); -/// -/// info(); -/// } -/// ``` -#[allow(clippy::match_wild_err_arm)] -pub fn register_error_handler(cb_value: Callback) { - let mut gaurd = match ERROR_HANDLER_LOCK.write() { - Ok(g) => g, - Err(_) => panic!("Failed to acquire lock to register error handler"), - }; - - *gaurd.deref_mut() = cb_value; -} - -/// Default error handler for error code returned by ArrayFire FFI calls -#[allow(non_snake_case)] -#[allow(clippy::match_wild_err_arm)] -pub fn HANDLE_ERROR(error_code: AfError) { - let gaurd = match ERROR_HANDLER_LOCK.read() { - Ok(g) => g, - Err(_) => panic!("Failed to acquire lock while handling FFI return value"), - }; - - (*gaurd.deref()).call(error_code); -} - -/// Fetch last error description as String -pub fn get_last_error() -> String { - let mut result: String = String::from("No Last Error"); - let mut tmp: *mut c_char = ::std::ptr::null_mut(); - let mut len: dim_t = 0; - unsafe { - af_get_last_error(&mut tmp, &mut len as *mut dim_t); - if len > 0 { - result = CStr::from_ptr(tmp).to_string_lossy().into_owned(); - free_host(tmp); - } - } - result -} diff --git a/src/core/event.rs b/src/core/event.rs deleted file mode 100644 index 674858c1c..000000000 --- a/src/core/event.rs +++ /dev/null @@ -1,155 +0,0 @@ -use super::defines::AfError; -use super::error::HANDLE_ERROR; -use super::util::af_event; - -use libc::c_int; -use std::default::Default; - -extern "C" { - fn af_create_event(out: *mut af_event) -> c_int; - fn af_delete_event(out: af_event) -> c_int; - fn af_mark_event(out: af_event) -> c_int; - fn af_enqueue_wait_event(out: af_event) -> c_int; - fn af_block_event(out: af_event) -> c_int; -} - -/// RAII construct to manage ArrayFire events -/// -/// ## Sharing Across Threads -/// -/// While sharing an Event with other threads, just move it across threads. -pub struct Event { - event_handle: af_event, -} - -unsafe impl Send for Event {} -// No borrowed references are to be shared for Events, hence no sync trait - -impl Default for Event { - fn default() -> Self { - let mut temp: af_event = std::ptr::null_mut(); - - let err_val = unsafe { af_create_event(&mut temp as *mut af_event) }; - HANDLE_ERROR(AfError::from(err_val)); - - Self { event_handle: temp } - } -} - -impl Event { - /// Marks the event on the active computation queue. - /// - /// If the event is enqueued/waited on later, any operations that are currently - /// enqueued on the event queue will be completed before any events that are - /// enqueued after the call to enqueue - pub fn mark(&self) { - let err_val = unsafe { af_mark_event(self.event_handle as af_event) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Enqueues the event and all enqueued events on the active queue - /// - /// All operations enqueued after a call to enqueue will not be executed - /// until operations on the queue when mark was called are complete - pub fn enqueue_wait(&self) { - let err_val = unsafe { af_enqueue_wait_event(self.event_handle as af_event) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Blocks the calling thread on events until all events on the computation - /// stream before mark was called are complete - pub fn block(&self) { - unsafe { - let err_val = af_block_event(self.event_handle as af_event); - HANDLE_ERROR(AfError::from(err_val)); - } - } -} - -impl Drop for Event { - fn drop(&mut self) { - let ret_val = unsafe { af_delete_event(self.event_handle as af_event) }; - match ret_val { - 0 => (), - _ => panic!("Failed to delete event resources: {}", ret_val), - } - } -} - -#[cfg(test)] -mod tests { - use super::super::arith::pow; - use super::super::device::{info, set_device}; - use super::super::event::Event; - use crate::{af_print, randu}; - use std::sync::mpsc; - use std::thread; - - #[test] - fn event_block() { - // This code example will try to compute the following expression - // using data-graph approach using threads, evens for illustration. - // - // (a * (b + c))^(d - 2) - // - // ANCHOR: event_block - - // Set active GPU/device on main thread on which - // subsequent Array objects are created - set_device(0); - info(); - - let a = randu!(10, 10); - let b = randu!(10, 10); - let c = randu!(10, 10); - let d = randu!(10, 10); - - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - set_device(0); - - let add_event = Event::default(); - - let add_res = b + c; - - add_event.mark(); - tx.send((add_res, add_event)).unwrap(); - - thread::sleep(std::time::Duration::new(10, 0)); - - let sub_event = Event::default(); - - let sub_res = d - 2; - - sub_event.mark(); - tx.send((sub_res, sub_event)).unwrap(); - }); - - let (add_res, add_event) = rx.recv().unwrap(); - - println!("Got first message, waiting for addition result ..."); - thread::sleep(std::time::Duration::new(5, 0)); - // Perhaps, do some other tasks - add_event.block(); - - println!("Got addition result, now scaling it ... "); - let scaled = a * add_res; - - let (sub_res, sub_event) = rx.recv().unwrap(); - - println!("Got message, waiting for subtraction result ..."); - thread::sleep(std::time::Duration::new(5, 0)); - // Perhaps, do some other tasks - sub_event.block(); - - let fin_res = pow(&scaled, &sub_res, false); - - af_print!( - "Final result of the expression: ((a * (b + c))^(d - 2))", - &fin_res - ); - - // ANCHOR_END: event_block - } -} diff --git a/src/core/index.rs b/src/core/index.rs deleted file mode 100644 index b4a1b2a2b..000000000 --- a/src/core/index.rs +++ /dev/null @@ -1,927 +0,0 @@ -use super::array::Array; -use super::defines::AfError; -use super::error::HANDLE_ERROR; -use super::seq::Seq; -use super::util::{af_array, af_index_t, dim_t, HasAfEnum, IndexableType}; - -use libc::{c_double, c_int, c_uint}; -use std::default::Default; -use std::marker::PhantomData; -use std::mem; - -extern "C" { - fn af_create_indexers(indexers: *mut af_index_t) -> c_int; - fn af_set_array_indexer(indexer: af_index_t, idx: af_array, dim: dim_t) -> c_int; - fn af_set_seq_indexer( - indexer: af_index_t, - idx: *const SeqInternal, - dim: dim_t, - is_batch: bool, - ) -> c_int; - fn af_release_indexers(indexers: af_index_t) -> c_int; - - fn af_index( - out: *mut af_array, - input: af_array, - ndims: c_uint, - index: *const SeqInternal, - ) -> c_int; - fn af_lookup(out: *mut af_array, arr: af_array, indices: af_array, dim: c_uint) -> c_int; - fn af_assign_seq( - out: *mut af_array, - lhs: af_array, - ndims: c_uint, - indices: *const SeqInternal, - rhs: af_array, - ) -> c_int; - fn af_index_gen( - out: *mut af_array, - input: af_array, - ndims: dim_t, - indices: af_index_t, - ) -> c_int; - fn af_assign_gen( - out: *mut af_array, - lhs: af_array, - ndims: dim_t, - indices: af_index_t, - rhs: af_array, - ) -> c_int; -} - -/// Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct) -/// -/// ## Sharing Across Threads -/// -/// While sharing an Indexer object with other threads, just move it across threads. At the -/// moment, one cannot share borrowed references across threads. -/// -/// # Examples -/// -/// Given below are examples illustrating correct and incorrect usage of Indexer struct. -/// -///

Correct Usage

-/// -/// ```rust -/// use arrayfire::{Array, Dim4, randu, index_gen, Indexer}; -/// -/// // Always be aware of the fact that, the `Seq` or `Array` objects -/// // that we intend to use for indexing via `Indexer` have to outlive -/// // the `Indexer` object created in this context. -/// -/// let dims = Dim4::new(&[1, 3, 1, 1]); -/// let indices = [1u8, 0, 1]; -/// let idx = Array::new(&indices, dims); -/// let values = [2.0f32, 5.0, 6.0]; -/// let arr = Array::new(&values, dims); -/// -/// let mut idxr = Indexer::default(); -/// -/// // `idx` is created much before idxr, thus will -/// // stay in scope at least as long as idxr -/// idxr.set_index(&idx, 0, None); -/// -/// index_gen(&arr, idxr); -/// ``` -/// -///

Incorrect Usage

-/// -/// ```rust,ignore -/// // Say, you create an Array on the fly and try -/// // to call set_index, it will throw the given below -/// // error or something similar to that -/// idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None); -/// ``` -/// -/// ```text -/// error: borrowed value does not live long enough -/// --> :16:55 -/// | -///16 | idxr.set_index(&Array::new(&[1, 0, 1], dims), 0, None); -/// | ---------------------------- ^ temporary value dropped here while still borrowed -/// | | -/// | temporary value created here -///... -///19 | } -/// | - temporary value needs to live until here -/// | -/// = note: consider using a `let` binding to increase its lifetime -/// ``` -pub struct Indexer<'object> { - handle: af_index_t, - count: usize, - marker: PhantomData<&'object ()>, -} - -unsafe impl<'object> Send for Indexer<'object> {} - -/// Trait bound indicating indexability -/// -/// Any object to be able to be passed on to [Indexer::set_index()](./struct.Indexer.html#method.set_index) method should implement this trait with appropriate implementation of `set` method. -pub trait Indexable { - /// Set indexing object for a given dimension - /// - /// `is_batch` parameter is not used in most cases as it has been provided in - /// ArrayFire C-API to enable GFOR construct in ArrayFire C++ API. This type - /// of construct/idea is not exposed in rust wrapper yet. So, the user would - /// just need to pass `None` to this parameter while calling this function. - /// Since we can't have default default values and we wanted to keep this - /// parameter for future use cases, we just made it an `std::Option`. - /// - /// # Parameters - /// - /// - `idxr` is mutable reference to [Indexer](./struct.Indexer.html) object which will - /// be modified to set `self` indexable along `dim` dimension. - /// - `dim` is the dimension along which `self` indexable will be used for indexing. - /// - `is_batch` is only used if `self` is [Seq](./struct.Seq.html) to indicate if indexing - /// along `dim` is a batched operation. - fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option); -} - -/// Enables [Array](./struct.Array.html) to be used to index another Array -/// -/// This is used in functions [index_gen](./fn.index_gen.html) and -/// [assign_gen](./fn.assign_gen.html) -impl Indexable for Array -where - T: HasAfEnum + IndexableType, -{ - fn set(&self, idxr: &mut Indexer, dim: u32, _is_batch: Option) { - let err_val = unsafe { af_set_array_indexer(idxr.get(), self.get(), dim as dim_t) }; - HANDLE_ERROR(AfError::from(err_val)); - } -} - -/// Enables [Seq](./struct.Seq.html) to be used to index another Array -/// -/// This is used in functions [index_gen](./fn.index_gen.html) and -/// [assign_gen](./fn.assign_gen.html) -impl Indexable for Seq -where - c_double: From, - T: Copy + IndexableType, -{ - fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option) { - let err_val = unsafe { - af_set_seq_indexer( - idxr.get(), - &SeqInternal::from_seq(self) as *const SeqInternal, - dim as dim_t, - is_batch.unwrap_or(false), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } -} - -impl<'object> Default for Indexer<'object> { - fn default() -> Self { - let mut temp: af_index_t = std::ptr::null_mut(); - let err_val = unsafe { af_create_indexers(&mut temp as *mut af_index_t) }; - HANDLE_ERROR(AfError::from(err_val)); - Self { - handle: temp, - count: 0, - marker: PhantomData, - } - } -} - -impl<'object> Indexer<'object> { - /// Create a new Indexer object and set the dimension specific index objects later - #[deprecated(since = "3.7.0", note = "Use Indexer::default() instead")] - pub fn new() -> Self { - let mut temp: af_index_t = std::ptr::null_mut(); - let err_val = unsafe { af_create_indexers(&mut temp as *mut af_index_t) }; - HANDLE_ERROR(AfError::from(err_val)); - Self { - handle: temp, - count: 0, - marker: PhantomData, - } - } - - /// Set either [Array](./struct.Array.html) or [Seq](./struct.Seq.html) to index an Array along `idx` dimension - pub fn set_index<'s, T>(&'s mut self, idx: &'object T, dim: u32, is_batch: Option) - where - T: Indexable + 'object, - { - idx.set(self, dim, is_batch); - self.count += 1; - } - - /// Get number of indexing objects set - pub fn len(&self) -> usize { - self.count - } - - /// Check if any indexing objects are set - pub fn is_empty(&self) -> bool { - self.count == 0 - } - - /// Get native(ArrayFire) resource handle - unsafe fn get(&self) -> af_index_t { - self.handle - } -} - -impl<'object> Drop for Indexer<'object> { - fn drop(&mut self) { - let ret_val = unsafe { af_release_indexers(self.handle as af_index_t) }; - match ret_val { - 0 => (), - _ => panic!("Failed to release indexers resource: {}", ret_val), - } - } -} - -/// Indexes the `input` Array using `seqs` Sequences -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, Seq, index, randu, print}; -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// let a = randu::(dims); -/// let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()]; -/// let sub = index(&a, seqs); -/// println!("a(seq(1, 3, 1), span)"); -/// print(&sub); -/// ``` -pub fn index(input: &Array, seqs: &[Seq]) -> Array -where - c_double: From, - IO: HasAfEnum, - T: Copy + HasAfEnum + IndexableType, -{ - let seqs: Vec = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_index( - &mut temp as *mut af_array, - input.get(), - seqs.len() as u32, - seqs.as_ptr() as *const SeqInternal, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Extract `row_num` row from `input` Array -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, randu, row, print}; -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// let a = randu::(dims); -/// println!("Grab last row of the random matrix"); -/// print(&a); -/// print(&row(&a, 4)); -/// ``` -pub fn row(input: &Array, row_num: i64) -> Array -where - T: HasAfEnum, -{ - let mut seqs = vec![Seq::new(row_num as f64, row_num as f64, 1.0)]; - for _d in 1..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set `row_num`^th row in `inout` Array to a new Array `new_row` -pub fn set_row(inout: &mut Array, new_row: &Array, row_num: i64) -where - T: HasAfEnum, -{ - let mut seqs = vec![Seq::new(row_num as f64, row_num as f64, 1.0)]; - for _d in 1..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_row) -} - -/// Get an Array with all rows from `first` to `last` in the `input` Array -pub fn rows(input: &Array, first: i64, last: i64) -> Array -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![Seq::new(first as f64, last as f64, step)]; - for _d in 1..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set rows from `first` to `last` in `inout` Array with rows from Array `new_rows` -pub fn set_rows(inout: &mut Array, new_rows: &Array, first: i64, last: i64) -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![Seq::new(first as f64, last as f64, step)]; - for _d in 1..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_rows) -} - -/// Extract `col_num` col from `input` Array -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, randu, col, print}; -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// let a = randu::(dims); -/// print(&a); -/// println!("Grab last col of the random matrix"); -/// print(&col(&a, 4)); -/// ``` -pub fn col(input: &Array, col_num: i64) -> Array -where - T: HasAfEnum, -{ - let mut seqs = vec![ - Seq::default(), - Seq::new(col_num as f64, col_num as f64, 1.0), - ]; - for _d in 2..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set `col_num`^th col in `inout` Array to a new Array `new_col` -pub fn set_col(inout: &mut Array, new_col: &Array, col_num: i64) -where - T: HasAfEnum, -{ - let mut seqs = vec![ - Seq::default(), - Seq::new(col_num as f64, col_num as f64, 1.0), - ]; - for _d in 2..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_col) -} - -/// Get all cols from `first` to `last` in the `input` Array -pub fn cols(input: &Array, first: i64, last: i64) -> Array -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![Seq::default(), Seq::new(first as f64, last as f64, step)]; - for _d in 2..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set cols from `first` to `last` in `inout` Array with cols from Array `new_cols` -pub fn set_cols(inout: &mut Array, new_cols: &Array, first: i64, last: i64) -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![Seq::default(), Seq::new(first as f64, last as f64, step)]; - for _d in 2..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_cols) -} - -/// Get `slice_num`^th slice from `input` Array -/// -/// Slices indicate that the indexing is along 3rd dimension -pub fn slice(input: &Array, slice_num: i64) -> Array -where - T: HasAfEnum, -{ - let mut seqs = vec![ - Seq::default(), - Seq::default(), - Seq::new(slice_num as f64, slice_num as f64, 1.0), - ]; - for _d in 3..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set slice `slice_num` in `inout` Array to a new Array `new_slice` -/// -/// Slices indicate that the indexing is along 3rd dimension -pub fn set_slice(inout: &mut Array, new_slice: &Array, slice_num: i64) -where - T: HasAfEnum, -{ - let mut seqs = vec![ - Seq::default(), - Seq::default(), - Seq::new(slice_num as f64, slice_num as f64, 1.0), - ]; - for _d in 3..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_slice) -} - -/// Get slices from `first` to `last` in `input` Array -/// -/// Slices indicate that the indexing is along 3rd dimension -pub fn slices(input: &Array, first: i64, last: i64) -> Array -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![ - Seq::default(), - Seq::default(), - Seq::new(first as f64, last as f64, step), - ]; - for _d in 3..input.dims().ndims() { - seqs.push(Seq::default()); - } - index(input, &seqs) -} - -/// Set `first` to `last` slices of `inout` Array to a new Array `new_slices` -/// -/// Slices indicate that the indexing is along 3rd dimension -pub fn set_slices(inout: &mut Array, new_slices: &Array, first: i64, last: i64) -where - T: HasAfEnum, -{ - let step: f64 = if first > last && last < 0 { -1.0 } else { 1.0 }; - let mut seqs = vec![ - Seq::default(), - Seq::default(), - Seq::new(first as f64, last as f64, step), - ]; - for _d in 3..inout.dims().ndims() { - seqs.push(Seq::default()); - } - assign_seq(inout, &seqs, new_slices) -} - -/// Lookup(hash) an Array using another Array -/// -/// Given a dimension `seq_dim`, `indices` are lookedup in `input` and returned as a new -/// Array if found -pub fn lookup(input: &Array, indices: &Array, seq_dim: i32) -> Array -where - T: HasAfEnum, - I: HasAfEnum + IndexableType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_lookup( - &mut temp as *mut af_array, - input.get() as af_array, - indices.get() as af_array, - seq_dim as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Assign(copy) content of an Array to another Array indexed by Sequences -/// -/// Assign `rhs` to `lhs` after indexing `lhs` -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{constant, Dim4, Seq, assign_seq, print}; -/// let mut a = constant(2.0 as f32, Dim4::new(&[5, 3, 1, 1])); -/// print(&a); -/// // 2.0 2.0 2.0 -/// // 2.0 2.0 2.0 -/// // 2.0 2.0 2.0 -/// // 2.0 2.0 2.0 -/// // 2.0 2.0 2.0 -/// -/// let b = constant(1.0 as f32, Dim4::new(&[3, 3, 1, 1])); -/// let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()]; -/// assign_seq(&mut a, seqs, &b); -/// -/// print(&a); -/// // 2.0 2.0 2.0 -/// // 1.0 1.0 1.0 -/// // 1.0 1.0 1.0 -/// // 1.0 1.0 1.0 -/// // 2.0 2.0 2.0 -/// ``` -pub fn assign_seq(lhs: &mut Array, seqs: &[Seq], rhs: &Array) -where - c_double: From, - I: HasAfEnum, - T: Copy + IndexableType, -{ - let seqs: Vec = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_assign_seq( - &mut temp as *mut af_array, - lhs.get() as af_array, - seqs.len() as c_uint, - seqs.as_ptr() as *const SeqInternal, - rhs.get() as af_array, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - let modified = temp.into(); - let _old_arr = mem::replace(lhs, modified); -} - -/// Index an Array using any combination of Array's and Sequence's -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Array, Dim4, Seq, print, randu, index_gen, Indexer}; -/// let values: [f32; 3] = [1.0, 2.0, 3.0]; -/// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); -/// let seq4gen = Seq::new(0.0, 2.0, 1.0); -/// let a = randu::(Dim4::new(&[5, 3, 1, 1])); -/// // [5 3 1 1] -/// // 0.0000 0.2190 0.3835 -/// // 0.1315 0.0470 0.5194 -/// // 0.7556 0.6789 0.8310 -/// // 0.4587 0.6793 0.0346 -/// // 0.5328 0.9347 0.0535 -/// -/// -/// let mut idxrs = Indexer::default(); -/// idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension -/// idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation -/// -/// let sub2 = index_gen(&a, idxrs); -/// println!("a(indices, seq(0, 2, 1))"); print(&sub2); -/// // [3 3 1 1] -/// // 0.1315 0.0470 0.5194 -/// // 0.7556 0.6789 0.8310 -/// // 0.4587 0.6793 0.0346 -/// ``` -pub fn index_gen(input: &Array, indices: Indexer) -> Array -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_index_gen( - &mut temp as *mut af_array, - input.get() as af_array, - indices.len() as dim_t, - indices.get() as af_index_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Assign an Array to another after indexing it using any combination of Array's and Sequence's -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Array, Dim4, Seq, print, randu, constant, Indexer, assign_gen}; -/// let values: [f32; 3] = [1.0, 2.0, 3.0]; -/// let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); -/// let seq4gen = Seq::new(0.0, 2.0, 1.0); -/// let mut a = randu::(Dim4::new(&[5, 3, 1, 1])); -/// // [5 3 1 1] -/// // 0.0000 0.2190 0.3835 -/// // 0.1315 0.0470 0.5194 -/// // 0.7556 0.6789 0.8310 -/// // 0.4587 0.6793 0.0346 -/// // 0.5328 0.9347 0.0535 -/// -/// let b = constant(2.0 as f32, Dim4::new(&[3, 3, 1, 1])); -/// -/// let mut idxrs = Indexer::default(); -/// idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension -/// idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation -/// -/// assign_gen(&mut a, &idxrs, &b); -/// println!("a(indices, seq(0, 2, 1))"); print(&a); -/// // [5 3 1 1] -/// // 0.0000 0.2190 0.3835 -/// // 2.0000 2.0000 2.0000 -/// // 2.0000 2.0000 2.0000 -/// // 2.0000 2.0000 2.0000 -/// // 0.5328 0.9347 0.0535 -/// ``` -pub fn assign_gen(lhs: &mut Array, indices: &Indexer, rhs: &Array) -where - T: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_assign_gen( - &mut temp as *mut af_array, - lhs.get() as af_array, - indices.len() as dim_t, - indices.get() as af_index_t, - rhs.get() as af_array, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - let modified = temp.into(); - let _old_arr = mem::replace(lhs, modified); -} - -#[repr(C)] -struct SeqInternal { - begin: c_double, - end: c_double, - step: c_double, -} - -impl SeqInternal { - fn from_seq(s: &Seq) -> Self - where - c_double: From, - T: Copy + IndexableType, - { - Self { - begin: From::from(s.begin()), - end: From::from(s.end()), - step: From::from(s.step()), - } - } -} - -#[cfg(test)] -mod tests { - use super::super::array::Array; - use super::super::data::constant; - use super::super::device::set_device; - use super::super::dim4::Dim4; - use super::super::index::{assign_gen, assign_seq, col, index, index_gen, row, Indexer}; - use super::super::index::{cols, rows, set_row, set_rows}; - use super::super::random::randu; - use super::super::seq::Seq; - - use crate::{dim4, seq, view}; - - #[test] - fn non_macro_seq_index() { - set_device(0); - // ANCHOR: non_macro_seq_index - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - //af_print!("a", a); - //a - //[5 5 1 1] - // 0.3990 0.5160 0.8831 0.9107 0.6688 - // 0.6720 0.3932 0.0621 0.9159 0.8434 - // 0.5339 0.2706 0.7089 0.0231 0.1328 - // 0.1386 0.9455 0.9434 0.2330 0.2657 - // 0.7353 0.1587 0.1227 0.2220 0.2299 - - // Index array using sequences - let seqs = &[Seq::new(1u32, 3, 1), Seq::default()]; - let _sub = index(&a, seqs); - //af_print!("a(seq(1,3,1), span)", sub); - // [3 5 1 1] - // 0.6720 0.3932 0.0621 0.9159 0.8434 - // 0.5339 0.2706 0.7089 0.0231 0.1328 - // 0.1386 0.9455 0.9434 0.2330 0.2657 - // ANCHOR_END: non_macro_seq_index - } - - #[test] - fn seq_index() { - set_device(0); - // ANCHOR: seq_index - let dims = dim4!(5, 5, 1, 1); - let a = randu::(dims); - let first3 = seq!(1:3:1); - let allindim2 = seq!(); - let _sub = view!(a[first3, allindim2]); - // ANCHOR_END: seq_index - } - - #[test] - fn non_macro_seq_assign() { - set_device(0); - // ANCHOR: non_macro_seq_assign - let mut a = constant(2.0_f32, dim4!(5, 3)); - //print(&a); - // 2.0 2.0 2.0 - // 2.0 2.0 2.0 - // 2.0 2.0 2.0 - // 2.0 2.0 2.0 - // 2.0 2.0 2.0 - - let b = constant(1.0_f32, dim4!(3, 3)); - let seqs = [seq!(1:3:1), seq!()]; - assign_seq(&mut a, &seqs, &b); - //print(&a); - // 2.0 2.0 2.0 - // 1.0 1.0 1.0 - // 1.0 1.0 1.0 - // 1.0 1.0 1.0 - // 2.0 2.0 2.0 - // ANCHOR_END: non_macro_seq_assign - } - - #[test] - fn non_macro_seq_array_index() { - set_device(0); - // ANCHOR: non_macro_seq_array_index - let values: [f32; 3] = [1.0, 2.0, 3.0]; - let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); - let seq4gen = Seq::new(0.0, 2.0, 1.0); - let a = randu::(Dim4::new(&[5, 3, 1, 1])); - // [5 3 1 1] - // 0.0000 0.2190 0.3835 - // 0.1315 0.0470 0.5194 - // 0.7556 0.6789 0.8310 - // 0.4587 0.6793 0.0346 - // 0.5328 0.9347 0.0535 - - let mut idxrs = Indexer::default(); - idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension - idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation - - let _sub2 = index_gen(&a, idxrs); - //println!("a(indices, seq(0, 2, 1))"); print(&sub2); - // [3 3 1 1] - // 0.1315 0.0470 0.5194 - // 0.7556 0.6789 0.8310 - // 0.4587 0.6793 0.0346 - // ANCHOR_END: non_macro_seq_array_index - } - - #[test] - fn seq_array_index() { - set_device(0); - // ANCHOR: seq_array_index - let values: [f32; 3] = [1.0, 2.0, 3.0]; - let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); - let seq4gen = seq!(0:2:1); - let a = randu::(Dim4::new(&[5, 3, 1, 1])); - let _sub2 = view!(a[indices, seq4gen]); - // ANCHOR_END: seq_array_index - } - - #[test] - fn non_macro_seq_array_assign() { - set_device(0); - // ANCHOR: non_macro_seq_array_assign - let values: [f32; 3] = [1.0, 2.0, 3.0]; - let indices = Array::new(&values, dim4!(3, 1, 1, 1)); - let seq4gen = seq!(0:2:1); - let mut a = randu::(dim4!(5, 3, 1, 1)); - // [5 3 1 1] - // 0.0000 0.2190 0.3835 - // 0.1315 0.0470 0.5194 - // 0.7556 0.6789 0.8310 - // 0.4587 0.6793 0.0346 - // 0.5328 0.9347 0.0535 - - let b = constant(2.0_f32, dim4!(3, 3, 1, 1)); - - let mut idxrs = Indexer::default(); - idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension - idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation - - let _sub2 = assign_gen(&mut a, &idxrs, &b); - //println!("a(indices, seq(0, 2, 1))"); print(&sub2); - // [5 3 1 1] - // 0.0000 0.2190 0.3835 - // 2.0000 2.0000 2.0000 - // 2.0000 2.0000 2.0000 - // 2.0000 2.0000 2.0000 - // 0.5328 0.9347 0.0535 - // ANCHOR_END: non_macro_seq_array_assign - } - - #[test] - fn setrow() { - set_device(0); - // ANCHOR: setrow - let a = randu::(dim4!(5, 5, 1, 1)); - //print(&a); - // [5 5 1 1] - // 0.6010 0.5497 0.1583 0.3636 0.6755 - // 0.0278 0.2864 0.3712 0.4165 0.6105 - // 0.9806 0.3410 0.3543 0.5814 0.5232 - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _r = row(&a, 4); - // [1 5 1 1] - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _c = col(&a, 4); - // [5 1 1 1] - // 0.6755 - // 0.6105 - // 0.5232 - // 0.5567 - // 0.7896 - // ANCHOR_END: setrow - } - - #[test] - fn get_row() { - set_device(0); - // ANCHOR: get_row - let a = randu::(dim4!(5, 5)); - // [5 5 1 1] - // 0.6010 0.5497 0.1583 0.3636 0.6755 - // 0.0278 0.2864 0.3712 0.4165 0.6105 - // 0.9806 0.3410 0.3543 0.5814 0.5232 - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _r = row(&a, -1); - // [1 5 1 1] - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _c = col(&a, -1); - // [5 1 1 1] - // 0.6755 - // 0.6105 - // 0.5232 - // 0.5567 - // 0.7896 - // ANCHOR_END: get_row - } - - #[test] - fn get_rows() { - set_device(0); - // ANCHOR: get_rows - let a = randu::(dim4!(5, 5)); - // [5 5 1 1] - // 0.6010 0.5497 0.1583 0.3636 0.6755 - // 0.0278 0.2864 0.3712 0.4165 0.6105 - // 0.9806 0.3410 0.3543 0.5814 0.5232 - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _r = rows(&a, -1, -2); - // [2 5 1 1] - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - let _c = cols(&a, -1, -3); - // [5 3 1 1] - // 0.1583 0.3636 0.6755 - // 0.3712 0.4165 0.6105 - // 0.3543 0.5814 0.5232 - // 0.6450 0.8962 0.5567 - // 0.9675 0.3712 0.7896 - // ANCHOR_END: get_rows - } - - #[test] - fn change_row() { - set_device(0); - - let v0: Vec = vec![true, true, true, true, true, true]; - let mut a0 = Array::new(&v0, dim4!(v0.len() as u64)); - - let v1: Vec = vec![false]; - let a1 = Array::new(&v1, dim4!(v1.len() as u64)); - - set_row(&mut a0, &a1, 2); - - let mut res = vec![true; a0.elements()]; - a0.host(&mut res); - - let gold = vec![true, true, false, true, true, true]; - - assert_eq!(gold, res); - } - - #[test] - fn change_rows() { - set_device(0); - - let v0: Vec = vec![true, true, true, true, true, true]; - let mut a0 = Array::new(&v0, dim4!(v0.len() as u64)); - - let v1: Vec = vec![false, false]; - let a1 = Array::new(&v1, dim4!(v1.len() as u64)); - - set_rows(&mut a0, &a1, 2, 3); - - let mut res = vec![true; a0.elements()]; - a0.host(&mut res); - - let gold = vec![true, true, false, false, true, true]; - - assert_eq!(gold, res); - } -} diff --git a/src/core/macros.rs b/src/core/macros.rs deleted file mode 100644 index 366f0cc80..000000000 --- a/src/core/macros.rs +++ /dev/null @@ -1,562 +0,0 @@ -/// Macro to print the current stats of ArrayFire's memory manager. -/// -/// `mem_info!` print 4 values: -/// -/// Name | Description -/// -------------------------|------------------------- -/// Allocated Bytes | Total number of bytes allocated by the memory manager -/// Allocated Buffers | Total number of buffers allocated -/// Locked (In Use) Bytes | Number of bytes that are in use by active arrays -/// Locked (In Use) Buffers | Number of buffers that are in use by active arrays -/// -/// The `Allocated Bytes` is always a multiple of the memory step size. The -/// default step size is 1024 bytes. This means when a buffer is to be -/// allocated, the size is always rounded up to a multiple of the step size. -/// You can use [get_mem_step_size](./fn.get_mem_step_size.html) to check the -/// current step size and [set_mem_step_size](./fn.set_mem_step_size.html) to -/// set a custom resolution size. -/// -/// The `Allocated Buffers` is the number of buffers that use up the allocated -/// bytes. This includes buffers currently in scope, as well as buffers marked -/// as free, ie, from arrays gone out of scope. The free buffers are available -/// for use by new arrays that might be created. -/// -/// The `Locked Bytes` is the number of bytes in use that cannot be -/// reallocated at the moment. The difference of Allocated Bytes and Locked -/// Bytes is the total bytes available for reallocation. -/// -/// The `Locked Buffers` is the number of buffer in use that cannot be -/// reallocated at the moment. The difference of Allocated Buffers and Locked -/// Buffers is the number of buffers available for reallocation. -/// -/// # Parameters -/// -/// - `msg` is the message that is printed to screen before printing stats -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, device_mem_info, print, randu, mem_info}; -/// -/// let dims = Dim4::new(&[5, 5, 1, 1]); -/// let a = randu::(dims); -/// print(&a); -/// mem_info!("Hello!"); -/// ``` -/// -/// Sample Output: -/// -/// ```text -/// AF Memory: Here -/// Allocated [ Bytes | Buffers ] = [ 4096 | 4 ] -/// In Use [ Bytes | Buffers ] = [ 2048 | 2 ] -/// ``` -#[macro_export] -macro_rules! mem_info { - [$msg: expr] => { - { - let (abytes, abuffs, lbytes, lbuffs) = $crate::device_mem_info(); - println!("AF Memory: {:?}", $msg); - println!("Allocated [Bytes | Buffers] = [ {} | {} ]", abytes, abuffs); - println!("In Use [Bytes | Buffers] = [ {} | {} ]", lbytes, lbuffs); - } - }; -} - -/// Join multiple Arrays along a given dimension -/// -/// All the Arrays provided to this macro should be of type `&Array` -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, join_many, print, randu}; -/// -/// let a = &randu::(Dim4::new(&[5, 3, 1, 1])); -/// let b = &randu::(Dim4::new(&[5, 3, 1, 1])); -/// let c = &randu::(Dim4::new(&[5, 3, 1, 1])); -/// let d = join_many![2; a, b, c]; -/// print(&d); -/// ``` -/// -/// # Panics -/// -/// This macro just calls [join_many](./fn.join_many.html) function after collecting all -/// the input arrays into a vector. -// Using macro to implement join many wrapper -#[macro_export] -macro_rules! join_many { - [$dim: expr; $($x:expr),+] => { - { - let mut temp_vec = Vec::new(); - $( - temp_vec.push($x); - )* - $crate::join_many($dim, temp_vec) - } - }; -} - -/// Print given message before printing out the Array to standard output -/// -/// # Examples -/// -/// ```rust -/// use arrayfire::{Dim4, print_gen, randu, af_print}; -/// let dims = Dim4::new(&[3, 1, 1, 1]); -/// let a = randu::(dims); -/// af_print!("Create a 5-by-3 matrix of random floats on the GPU", a); -/// ``` -/// -#[macro_export] -macro_rules! af_print { - [$msg: expr, $x: expr] => { - { - $crate::print_gen(String::from($msg), &$x, Some(4)); - } - }; -} - -/// Create a dim4 object from provided dimensions -/// -/// The user can pass 1 or more sizes and the left over values will default to 1. -#[macro_export] -macro_rules! dim4 { - ($dim0:expr) => { - $crate::Dim4::new(&[$dim0, 1, 1, 1]) - }; - ($dim0:expr, $dim1:expr) => { - $crate::Dim4::new(&[$dim0, $dim1, 1, 1]) - }; - ($dim0:expr, $dim1:expr, $dim2:expr) => { - $crate::Dim4::new(&[$dim0, $dim1, $dim2, 1]) - }; - ($dim0:expr, $dim1:expr, $dim2:expr, $dim3:expr) => { - $crate::Dim4::new(&[$dim0, $dim1, $dim2, $dim3]) - }; -} - -/// Create a sequence object -/// -/// If type is not provided, then the Seq will default to i32 type -#[macro_export] -macro_rules! seq { - () => { - $crate::Seq::::default() - }; - ($sty:ty; $start:literal : $end:literal : $step:literal) => { - $crate::Seq::<$sty>::new($start, $end, $step) - }; - ($start:literal : $end:literal : $step:literal) => { - $crate::Seq::::new($start, $end, $step) - }; - ($sty:ty; $start:expr , $end:expr , $step:expr) => { - $crate::Seq::<$sty>::new($start, $end, $step) - }; - ($start:expr , $end:expr , $step:expr) => { - $crate::Seq::::new($start, $end, $step) - }; -} - -/// Indexing into an existing Array -/// -/// This macro call with return an Array that has a view of another Array. The Array returned due to -/// the indexing operation will follow copy-on-write semantics. The Array identifier taken by this -/// macro is passed to the relevant internal functions as a borrowed reference. Thus, this identifier -/// will be still available for futher use after the macro call. -/// -/// The following types of inputs are matched by this macro. -/// -/// - A simple Array identifier. -/// - An Array with slicing info for indexing. -/// - An Array with slicing info and other arrays used for indexing. -/// -/// Examples on how to use this macro are provided in the [tutorials book][1] -/// -/// [1]: http://arrayfire.org/arrayfire-rust/book/indexing.html -#[macro_export] -macro_rules! view { - (@af_max_dims) => { - 4 - }; - ( $array_ident:ident ) => { - $array_ident.clone() - }; - ( $array_ident:ident [ $($start:literal : $end:literal : $step:literal),+ ] ) => { - { - #[allow(non_snake_case)] - let AF_MAX_DIMS: usize = view!(@af_max_dims); - let mut seq_vec = Vec::<$crate::Seq>::with_capacity(AF_MAX_DIMS); - $( - seq_vec.push($crate::seq!($start:$end:$step)); - )* - for _d in seq_vec.len()..$array_ident.dims().ndims() { - seq_vec.push($crate::seq!()); - } - $crate::index(&$array_ident, &seq_vec) - } - }; - (@set_indexer $idim:expr, $idxr:ident, $lterm:expr) => { - { - $idxr.set_index(&$lterm, $idim, None); - } - }; - (@set_indexer $idim:expr, $idxr:ident, $hterm:expr, $($tterm:expr),*) => { - { - $idxr.set_index(&$hterm, $idim, None); - view!(@set_indexer $idim + 1, $idxr, $($tterm),*); - } - }; - ($array_ident:ident [ $($_e:expr),+ ]) => { - { - let mut idxrs = $crate::Indexer::default(); - view!(@set_indexer 0, idxrs, $($_e),*); - $crate::index_gen(&$array_ident, idxrs) - } - }; -} - -/// Macro to evaluate individual Arrays or assignment operations -/// -/// - Evaluate on one or more Array identifiers: essentially calls [Array::eval][4] on each of those -/// Array objects individually. -/// -/// ```rust -/// use arrayfire::{dim4, eval, randu}; -/// let dims = dim4!(5, 5); -/// let a = randu::(dims); -/// let b = a.clone(); -/// let c = a.clone(); -/// let d = a.clone(); -/// let x = a - b; -/// let y = c * d; -/// eval!(&x, &y); -/// ``` -/// -/// - Evaluate assignment operations: This is essentially syntactic sugar for modifying portions of -/// Array with another Array using a combination of [Sequences][1] and/or [Array][2] objects. -/// Full examples for this use case are provided in the [tutorials book][3] -/// -/// [1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Seq.html -/// [2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html -/// [3]: http://arrayfire.org/arrayfire-rust/book/indexing.html -/// [4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.eval -#[macro_export] -macro_rules! eval { - ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] = - $r:ident [ $($rb:literal : $re:literal : $rs:literal),+ ]) => { - { - #[allow(non_snake_case)] - let AF_MAX_DIMS: usize = view!(@af_max_dims); - let mut seq_vec = Vec::<$crate::Seq>::with_capacity(AF_MAX_DIMS); - $( - seq_vec.push($crate::seq!($lb:$le:$ls)); - )* - let mut idxrs = $crate::Indexer::default(); - for i in 0..seq_vec.len() { - idxrs.set_index(&seq_vec[i], i as u32, None); - } - let eq_rterm = $crate::view!($r[ $($rb:$re:$rs),+ ]); - $crate::assign_gen(&mut $l, &idxrs, &eq_rterm); - } - }; - ( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] = $r:expr ) => { - { - #[allow(non_snake_case)] - let AF_MAX_DIMS: usize = view!(@af_max_dims); - let mut seq_vec = Vec::<$crate::Seq>::with_capacity(AF_MAX_DIMS); - $( - seq_vec.push($crate::seq!($lb:$le:$ls)); - )* - let mut idxrs = $crate::Indexer::default(); - for i in 0..seq_vec.len() { - idxrs.set_index(&seq_vec[i], i as u32, None); - } - $crate::assign_gen(&mut $l, &idxrs, &$r); - } - }; - ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:ident [ $($rhs_e:expr),+ ]) => { - { - let eq_rterm = $crate::view!($rhs[ $($rhs_e),+ ]); - let mut idxrs = $crate::Indexer::default(); - view!(@set_indexer 0, idxrs, $($lhs_e),*); - $crate::assign_gen(&mut $lhs, &idxrs, &eq_rterm); - } - }; - ($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:expr) => { - { - let mut idxrs = $crate::Indexer::default(); - view!(@set_indexer 0, idxrs, $($lhs_e),*); - $crate::assign_gen(&mut $lhs, &idxrs, &$rhs); - } - }; - [$($x:expr),+] => { - { - let mut temp_vec = Vec::new(); - $( - temp_vec.push($x); - )* - $crate::eval_multiple(temp_vec) - } - }; -} - -/// Create an array of given shape filled with a single value a.k.a constant array -/// -/// # Examples -/// -/// ```rust -/// # use arrayfire::{constant}; -/// let _zeros_1d = constant!(0.0f32; 10); -/// let _ones_3d = constant!(1u32; 3, 3, 3); -/// -/// let dim = 10; -/// let mix_shape = constant!(42.0f32; dim, 10); -/// ``` -#[macro_export] -macro_rules! constant { - ($value:expr; $($dim:expr),+) => { - $crate::constant($value, $crate::dim4!($($dim),*)) - }; -} - -/// Create an array of given shape sampled from uniform distribution -/// -/// If no type argument is specified, the data type defaults to 32 bit floats. -/// -/// # Examples -/// -/// ```rust -/// # use arrayfire::{randu}; -/// let mat10x10 = randu!(10, 10); -/// ``` -#[macro_export] -macro_rules! randu { - ($($dim:expr),+) => { $crate::randu::($crate::dim4!($($dim),*)) }; - ($type:ty; $($dim:expr),+) => { $crate::randu::<$type>($crate::dim4!($($dim),*)) }; -} - -/// Create an array of given shape sampled from normal distribution -/// -/// If no type argument is specified, the data type defaults to 32 bit floats. -/// -/// # Examples -/// -/// ```rust -/// # use arrayfire::{randn}; -/// let mat10x10 = randn!(10, 10); -/// ``` -#[macro_export] -macro_rules! randn { - ($($dim:expr),+) => { $crate::randn::($crate::dim4!($($dim),*)) }; - ($type:ty; $($dim:expr),+) => { $crate::randn::<$type>($crate::dim4!($($dim),*)) }; -} - -#[cfg(test)] -mod tests { - use super::super::array::Array; - use super::super::data::constant; - use super::super::device::set_device; - use super::super::index::{index, rows, set_rows}; - use super::super::random::randu; - - #[test] - fn dim4_construction() { - let dim1d = dim4!(2); - let dim2d = dim4!(2, 3); - let dim3d = dim4!(2, 3, 4); - let dim4d = dim4!(2, 3, 4, 2); - let _dimn = dim4!(dim1d[0], dim2d[1], dim3d[2], dim4d[3]); - } - - #[test] - fn seq_construction() { - let default_seq = seq!(); - let _range_1_to_10_step_1 = seq!(0:9:1); - let _range_1_to_10_step_1_2 = seq!(f32; 0.0:9.0:1.5); - let _range_from_exprs = seq!(default_seq.begin(), default_seq.end(), default_seq.step()); - let _range_from_exprs2 = seq!(f32; default_seq.begin() as f32, - default_seq.end() as f32, default_seq.step() as f32); - } - - #[test] - fn seq_view() { - set_device(0); - let mut dim4d = dim4!(5, 3, 2, 1); - dim4d[2] = 1; - - let a = randu::(dim4d); - let seqs = &[seq!(1:3:1), seq!()]; - let _sub = index(&a, seqs); - } - - #[test] - fn seq_view2() { - set_device(0); - // ANCHOR: seq_view2 - let a = randu::(dim4!(5, 5)); - let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis - - // ANCHOR_END: seq_view2 - } - - #[test] - fn view_macro() { - set_device(0); - let dims = dim4!(5, 5, 2, 1); - let a = randu::(dims); - let b = a.clone(); - let c = a.clone(); - let d = a.clone(); - let e = a.clone(); - - let _v = view!(a); - - let _m = view!(c[1:3:1, 1:3:2]); - - let x = seq!(1:3:1); - let y = seq!(1:3:2); - let _u = view!(b[x, y]); - - let values: [u32; 3] = [1, 2, 3]; - let indices = Array::new(&values, dim4!(3, 1, 1, 1)); - let indices2 = Array::new(&values, dim4!(3, 1, 1, 1)); - - let _w = view!(d[indices, indices2]); - - let _z = view!(e[indices, y]); - } - - #[test] - fn eval_assign_seq_indexed_array() { - set_device(0); - let dims = dim4!(5, 5); - let mut a = randu::(dims); - //print(&a); - //[5 5 1 1] - // 0.6010 0.5497 0.1583 0.3636 0.6755 - // 0.0278 0.2864 0.3712 0.4165 0.6105 - // 0.9806 0.3410 0.3543 0.5814 0.5232 - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - - let b = randu::(dims); - //print(&b); - //[5 5 1 1] - // 0.8966 0.5143 0.0123 0.7917 0.2522 - // 0.0536 0.3670 0.3988 0.1654 0.9644 - // 0.5775 0.3336 0.9787 0.8657 0.4711 - // 0.2908 0.0363 0.2308 0.3766 0.3637 - // 0.9941 0.5349 0.6244 0.7331 0.9643 - - let d0 = seq!(1:2:1); - let d1 = seq!(1:2:1); - let s0 = seq!(1:2:1); - let s1 = seq!(1:2:1); - eval!(a[d0, d1] = b[s0, s1]); - //print(&a); - //[5 5 1 1] - // 0.6010 0.5497 0.1583 0.3636 0.6755 - // 0.0278 0.3670 0.3988 0.4165 0.6105 - // 0.9806 0.3336 0.9787 0.5814 0.5232 - // 0.2126 0.7509 0.6450 0.8962 0.5567 - // 0.0655 0.4105 0.9675 0.3712 0.7896 - } - - #[test] - fn eval_assign_array_to_seqd_array() { - set_device(0); - // ANCHOR: macro_seq_assign - let mut a = randu::(dim4!(5, 5)); - let b = randu::(dim4!(2, 2)); - eval!(a[1:2:1, 1:2:1] = b); - // ANCHOR_END: macro_seq_assign - } - - #[test] - fn macro_seq_array_assign() { - set_device(0); - // ANCHOR: macro_seq_array_assign - let values: [f32; 3] = [1.0, 2.0, 3.0]; - let indices = Array::new(&values, dim4!(3)); - let seq4gen = seq!(0:2:1); - let mut a = randu::(dim4!(5, 3)); - - let b = constant(2.0_f32, dim4!(3, 3)); - - eval!(a[indices, seq4gen] = b); - // ANCHOR_END: macro_seq_array_assign - } - - #[test] - fn constant_macro() { - set_device(0); - let _zeros_1d = constant!(0.0f32; 10); - let _zeros_2d = constant!(0.0f64; 5, 5); - let _ones_3d = constant!(1u32; 3, 3, 3); - let _twos_4d = constant!(2u16; 2, 2, 2, 2); - - let dim = 10; - let _mix_shape = constant!(42.0f32; dim, 10); - } - - #[test] - fn rand_macro() { - set_device(0); - let _ru5x5 = randu!(5, 5); - let _rn5x5 = randn!(5, 5); - let _ruu32_5x5 = randu!(u32; 5, 5); - let _ruu8_5x5 = randu!(u8; 5, 5); - } - - #[test] - fn match_eval_macro_with_set_rows() { - set_device(0); - - let inpt = vec![true, true, true, true, true, true, true, true, true, true]; - let gold = vec![ - true, true, false, false, true, true, true, false, false, true, - ]; - - let mut orig_arr = Array::new(&inpt, dim4!(5, 2)); - let mut orig_cln = orig_arr.clone(); - - let new_vals = vec![false, false, false, false]; - let new_arr = Array::new(&new_vals, dim4!(2, 2)); - - eval!( orig_arr[2:3:1,1:1:0] = new_arr ); - let mut res1 = vec![true; orig_arr.elements()]; - orig_arr.host(&mut res1); - - set_rows(&mut orig_cln, &new_arr, 2, 3); - let mut res2 = vec![true; orig_cln.elements()]; - orig_cln.host(&mut res2); - - assert_eq!(gold, res1); - assert_eq!(res1, res2); - } - - #[test] - fn match_view_macro_with_get_rows() { - set_device(0); - - let inpt: Vec = (0..10).collect(); - let gold: Vec = vec![2, 3, 7, 8]; - - println!("input {:?}", inpt); - println!("gold {:?}", gold); - - let orig_arr = Array::new(&inpt, dim4!(5, 2)); - - let view_out = view!( orig_arr[2:3:1] ); - let mut res1 = vec![0i32; view_out.elements()]; - view_out.host(&mut res1); - - let rows_out = rows(&orig_arr, 2, 3); - let mut res2 = vec![0i32; rows_out.elements()]; - rows_out.host(&mut res2); - - assert_eq!(gold, res1); - assert_eq!(res1, res2); - } -} diff --git a/src/core/mod.rs b/src/core/mod.rs deleted file mode 100644 index 173764f05..000000000 --- a/src/core/mod.rs +++ /dev/null @@ -1,51 +0,0 @@ -#[cfg(feature = "arithmetic")] -pub use arith::*; -#[cfg(feature = "arithmetic")] -mod arith; - -pub use array::*; -mod array; - -pub use backend::*; -mod backend; - -#[cfg(feature = "data")] -pub use data::*; -#[cfg(feature = "data")] -mod data; - -pub use defines::*; -mod defines; - -pub use dim4::Dim4; -mod dim4; - -pub use device::*; -mod device; - -pub use error::*; -mod error; - -pub use event::*; -mod event; - -#[cfg(feature = "indexing")] -pub use index::*; -#[cfg(feature = "indexing")] -mod index; - -#[cfg(feature = "macros")] -mod macros; - -#[cfg(feature = "random")] -pub use random::*; -#[cfg(feature = "random")] -mod random; - -#[cfg(feature = "indexing")] -pub use seq::Seq; -#[cfg(feature = "indexing")] -mod seq; - -pub use util::*; -mod util; diff --git a/src/core/num.rs b/src/core/num.rs deleted file mode 100644 index 73eca474b..000000000 --- a/src/core/num.rs +++ /dev/null @@ -1,56 +0,0 @@ - -pub trait Zero { - fn zero() -> Self; -} - -pub trait One { - fn one() -> Self; -} - -macro_rules! zero_impl { - ( $t:ident, $z:expr ) => { - impl Zero for $t { - fn zero() -> Self { - $z - } - } - }; -} - -zero_impl!(u8, 0); -zero_impl!(u16, 0); -zero_impl!(u32, 0); -zero_impl!(u64, 0); -zero_impl!(usize, 0); -zero_impl!(i8, 0); -zero_impl!(i16, 0); -zero_impl!(i32, 0); -zero_impl!(i64, 0); -zero_impl!(isize, 0); -zero_impl!(f32, 0.0); -zero_impl!(f64, 0.0); -zero_impl!(half::f16, half::f16::from_f32(0.0)); - -macro_rules! one_impl { - ( $t:ident, $o:expr ) => { - impl One for $t { - fn one() -> Self { - $o - } - } - }; -} - -one_impl!(u8, 1); -one_impl!(u16, 1); -one_impl!(u32, 1); -one_impl!(u64, 1); -one_impl!(usize, 1); -one_impl!(i8, 1); -one_impl!(i16, 1); -one_impl!(i32, 1); -one_impl!(i64, 1); -one_impl!(isize, 1); -one_impl!(f32, 1.0); -one_impl!(f64, 1.0); -one_impl!(half::f16, half::f16::from_f32(1.0)); diff --git a/src/core/random.rs b/src/core/random.rs deleted file mode 100644 index f05dd6063..000000000 --- a/src/core/random.rs +++ /dev/null @@ -1,368 +0,0 @@ -use super::array::Array; -use super::defines::{AfError, RandomEngineType}; -use super::dim4::Dim4; -use super::error::HANDLE_ERROR; -use super::util::{af_array, af_random_engine, dim_t, u64_t, FloatingPoint, HasAfEnum}; - -use libc::{c_int, c_uint}; - -extern "C" { - fn af_set_seed(seed: u64_t) -> c_int; - fn af_get_seed(seed: *mut u64_t) -> c_int; - - fn af_randu(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint) -> c_int; - fn af_randn(out: *mut af_array, ndims: c_uint, dims: *const dim_t, afdtype: c_uint) -> c_int; - - fn af_create_random_engine(engine: *mut af_random_engine, rtype: c_uint, seed: u64_t) -> c_int; - fn af_retain_random_engine( - engine: *mut af_random_engine, - inputEngine: af_random_engine, - ) -> c_int; - fn af_random_engine_set_type(engine: *mut af_random_engine, rtpye: c_uint) -> c_int; - fn af_random_engine_get_type(rtype: *mut c_uint, engine: af_random_engine) -> c_int; - fn af_random_engine_set_seed(engine: *mut af_random_engine, seed: u64_t) -> c_int; - fn af_random_engine_get_seed(seed: *mut u64_t, engine: af_random_engine) -> c_int; - fn af_release_random_engine(engine: af_random_engine) -> c_int; - - fn af_get_default_random_engine(engine: *mut af_random_engine) -> c_int; - fn af_set_default_random_engine_type(rtype: c_uint) -> c_int; - - fn af_random_uniform( - out: *mut af_array, - ndims: c_uint, - dims: *const dim_t, - aftype: c_uint, - engine: af_random_engine, - ) -> c_int; - fn af_random_normal( - out: *mut af_array, - ndims: c_uint, - dims: *const dim_t, - aftype: c_uint, - engine: af_random_engine, - ) -> c_int; -} - -/// Set seed for random number generation -pub fn set_seed(seed: u64) { - let err_val = unsafe { af_set_seed(seed as u64_t) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Get the seed of random number generator -pub fn get_seed() -> u64 { - let mut ret_val: u64 = 0; - - let err_val = unsafe { af_get_seed(&mut ret_val as *mut u64_t) }; - HANDLE_ERROR(AfError::from(err_val)); - - ret_val -} - -macro_rules! data_gen_def { - [$doc_str: expr, $fn_name:ident, $ffi_name: ident, $($type_trait: ident),+] => ( - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `dims` is the output dimensions - /// - ///# Return Values - /// - /// An Array with random values. - pub fn $fn_name(dims: Dim4) -> Array - where $( T: $type_trait, )* { - let aftype = T::get_af_dtype(); - unsafe { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = $ffi_name(&mut temp as *mut af_array, - dims.ndims() as c_uint, dims.get().as_ptr() as *const dim_t, - aftype as c_uint); - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - } - ) -} - -data_gen_def!( - "Create random numbers from uniform distribution", - randu, - af_randu, - HasAfEnum -); -data_gen_def!( - "Create random numbers from normal distribution", - randn, - af_randn, - HasAfEnum, - FloatingPoint -); - -/// Random number generator engine -/// -/// This is a wrapper for ArrayFire's native random number generator engine. -/// -/// ## Sharing Across Threads -/// -/// While sharing this object with other threads, there is no need to wrap -/// this in an Arc object unless only one such object is required to exist. -/// The reason being that ArrayFire's internal details that are pointed to -/// by the RandoMEngine handle are appropriately reference counted in thread safe -/// manner. However, if you need to modify RandomEngine object, then please do wrap -/// the object using a Mutex or Read-Write lock. -pub struct RandomEngine { - handle: af_random_engine, -} - -unsafe impl Send for RandomEngine {} - -/// Used for creating RandomEngine object from native resource id -impl From for RandomEngine { - fn from(t: af_random_engine) -> Self { - Self { handle: t } - } -} - -impl RandomEngine { - /// Create a new random engine object - /// - /// # Parameters - /// - /// - `rengine` can be value of [RandomEngineType](./enum.RandomEngineType.html) enum. - /// - `seed` is the initial seed value - /// - /// # Return Values - /// - /// A object of type RandomEngine - pub fn new(rengine: RandomEngineType, seed: Option) -> Self { - let mut temp: af_random_engine = std::ptr::null_mut(); - let err_val = unsafe { - af_create_random_engine( - &mut temp as *mut af_random_engine, - rengine as c_uint, - seed.unwrap_or(0u64), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - RandomEngine { handle: temp } - } - - /// Get random engine type - pub fn get_type(&self) -> RandomEngineType { - let mut temp: u32 = 0; - - let err_val = unsafe { af_random_engine_get_type(&mut temp as *mut c_uint, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - - RandomEngineType::from(temp) - } - - /// Get random engine type - pub fn set_type(&mut self, engine_type: RandomEngineType) { - let err_val = unsafe { - af_random_engine_set_type( - &mut self.handle as *mut af_random_engine, - engine_type as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set seed for random engine - pub fn set_seed(&mut self, seed: u64) { - let err_val = unsafe { - af_random_engine_set_seed(&mut self.handle as *mut af_random_engine, seed as u64_t) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Get seed of the random engine - pub fn get_seed(&self) -> u64 { - let mut seed: u64 = 0; - - let err_val = unsafe { af_random_engine_get_seed(&mut seed as *mut u64_t, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - - seed - } - - /// Returns the native FFI handle for Rust object `RandomEngine` - unsafe fn get(&self) -> af_random_engine { - self.handle - } -} - -/// Increment reference count of RandomEngine's native resource -impl Clone for RandomEngine { - fn clone(&self) -> Self { - let mut temp: af_random_engine = std::ptr::null_mut(); - let err_val = - unsafe { af_retain_random_engine(&mut temp as *mut af_random_engine, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - RandomEngine::from(temp) - } -} - -/// Free RandomEngine's native resource -impl Drop for RandomEngine { - fn drop(&mut self) { - let err_val = unsafe { af_release_random_engine(self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - } -} - -#[cfg(feature = "afserde")] -mod afserde { - // Reimport required from super scope - use super::{RandomEngine, RandomEngineType}; - - use serde::de::Deserializer; - use serde::ser::Serializer; - use serde::{Deserialize, Serialize}; - - #[derive(Debug, Serialize, Deserialize)] - struct RandEngine { - engine_type: RandomEngineType, - seed: u64, - } - - /// Serialize Implementation of Array - impl Serialize for RandomEngine { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let r = RandEngine { - engine_type: self.get_type(), - seed: self.get_seed(), - }; - r.serialize(serializer) - } - } - - /// Deserialize Implementation of Array - #[cfg(feature = "afserde")] - impl<'de> Deserialize<'de> for RandomEngine { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - match RandEngine::deserialize(deserializer) { - Ok(r) => Ok(RandomEngine::new(r.engine_type, Some(r.seed))), - Err(err) => Err(err), - } - } - } -} - -/// Get default random engine -pub fn get_default_random_engine() -> RandomEngine { - let mut temp: af_random_engine = std::ptr::null_mut(); - let mut err_val = unsafe { af_get_default_random_engine(&mut temp as *mut af_random_engine) }; - HANDLE_ERROR(AfError::from(err_val)); - let mut handle: af_random_engine = std::ptr::null_mut(); - err_val = unsafe { af_retain_random_engine(&mut handle as *mut af_random_engine, temp) }; - HANDLE_ERROR(AfError::from(err_val)); - RandomEngine { handle } -} - -/// Set the random engine type for default random number generator -/// -/// # Parameters -/// -/// - `rtype` can take one of the values of enum [RandomEngineType](./enum.RandomEngineType.html) -pub fn set_default_random_engine_type(rtype: RandomEngineType) { - let err_val = unsafe { af_set_default_random_engine_type(rtype as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Generate array of uniform numbers using a random engine -/// -/// # Parameters -/// -/// - `dims` is output array dimensions -/// - `engine` is an object of type [RandomEngine](./struct.RandomEngine.html) -/// -/// # Return Values -/// -/// An Array with uniform numbers generated using random engine -pub fn random_uniform(dims: Dim4, engine: &RandomEngine) -> Array -where - T: HasAfEnum, -{ - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_random_uniform( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - aftype as c_uint, - engine.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Generate array of normal numbers using a random engine -/// -/// # Parameters -/// -/// - `dims` is output array dimensions -/// - `engine` is an object of type [RandomEngine](./struct.RandomEngine.html) -/// -/// # Return Values -/// -/// An Array with normal numbers generated using random engine -pub fn random_normal(dims: Dim4, engine: &RandomEngine) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_random_normal( - &mut temp as *mut af_array, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const dim_t, - aftype as c_uint, - engine.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -#[cfg(test)] -mod tests { - #[cfg(feature = "afserde")] - mod serde_tests { - use super::super::RandomEngine; - use crate::core::defines::RandomEngineType; - - #[test] - #[cfg(feature = "afserde")] - fn random_engine_serde_bincode() { - // ANCHOR: rng_bincode_serde_snippet - use RandomEngineType::THREEFRY_2X32_16; - - let input = RandomEngine::new(THREEFRY_2X32_16, Some(2047)); - let encoded = match bincode::serialize(&input) { - Ok(encoded) => encoded, - Err(_) => vec![], - }; - // Save to disk or anything else required - - // Load different object if required - let decoded: RandomEngine = bincode::deserialize(&encoded).unwrap(); - // ANCHOR_END: rng_bincode_serde_snippet - - assert_eq!(input.get_seed(), decoded.get_seed()); - assert_eq!(input.get_type(), decoded.get_type()); - } - } -} diff --git a/src/core/seq.rs b/src/core/seq.rs deleted file mode 100644 index 84b08fea7..000000000 --- a/src/core/seq.rs +++ /dev/null @@ -1,92 +0,0 @@ -use num::{One, Zero}; - -#[cfg(feature = "afserde")] -use serde::{Deserialize, Serialize}; -use std::default::Default; -use std::fmt; - -use super::util::IndexableType; - -/// Sequences are used for indexing Arrays -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))] -#[repr(C)] -pub struct Seq { - begin: T, - end: T, - step: T, -} - -/// Default `Seq` spans all the elements along a dimension -impl Default for Seq -where - T: One + Zero + IndexableType, -{ - fn default() -> Self { - Self { - begin: One::one(), - end: One::one(), - step: Zero::zero(), - } - } -} - -/// Enables use of `Seq` with `{}` format in print statements -impl fmt::Display for Seq -where - T: fmt::Display + IndexableType, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "[begin: {}, end: {}, step: {}]", - self.begin, self.end, self.step - ) - } -} - -impl Seq -where - T: Copy + IndexableType, -{ - /// Create a `Seq` that goes from `begin` to `end` at a step size of `step` - pub fn new(begin: T, end: T, step: T) -> Self { - Self { begin, end, step } - } - - /// Get begin index of Seq - pub fn begin(&self) -> T { - self.begin - } - - /// Get end index of Seq - pub fn end(&self) -> T { - self.end - } - - /// Get step size of Seq - pub fn step(&self) -> T { - self.step - } -} - -#[cfg(test)] -mod tests { - #[cfg(feature = "afserde")] - #[test] - fn seq_serde() { - use super::Seq; - use crate::seq; - - // ANCHOR: seq_json_serde_snippet - let original = seq!(1:2:1); - let serd = match serde_json::to_string(&original) { - Ok(serialized_str) => serialized_str, - Err(e) => e.to_string(), - }; - - let deserd: Seq = serde_json::from_str(&serd).unwrap(); - assert_eq!(deserd, original); - // ANCHOR_END: seq_json_serde_snippet - } -} diff --git a/src/core/util.rs b/src/core/util.rs deleted file mode 100644 index 5a626d52e..000000000 --- a/src/core/util.rs +++ /dev/null @@ -1,900 +0,0 @@ -use super::defines::{ - AfError, BinaryOp, ColorMap, ConvDomain, ConvMode, DType, InterpType, MatProp, MatchType, - RandomEngineType, SparseFormat, -}; -use super::error::HANDLE_ERROR; - -use half::f16; -use libc::{c_int, c_uint, c_void, size_t}; -use num::Complex; -use std::convert::From; -use std::mem; -use std::ops::BitOr; - -/// Short type alias for Complex single precision type -pub type c32 = Complex; -/// Short type alias for Complex double precision type -pub type c64 = Complex; -/// ArrayFire FFI Type alias for libc's signed long long -pub type dim_t = libc::c_longlong; -/// ArrayFire FFI Type alias for libc's unsigned long long -pub type u64_t = libc::c_ulonglong; -/// ArrayFire FFI Type alias for libc's void* -pub type void_ptr = *mut libc::c_void; - -/// ArrayFire FFI Type alias for af_array -pub type af_array = *mut libc::c_void; -/// ArrayFire FFI Type alias for af_event -pub type af_event = *mut libc::c_void; -/// ArrayFire FFI Type alias for af_indexers_t -pub type af_index_t = *mut libc::c_void; -/// ArrayFire FFI Type alias for af_features -pub type af_features = *const libc::c_void; -/// ArrayFire FFI Type alias for af_random_engine -pub type af_random_engine = *mut libc::c_void; -/// ArrayFire FFI Type alias for af_window -pub type af_window = *mut libc::c_void; - -extern "C" { - fn af_get_size_of(size: *mut size_t, aftype: c_uint) -> c_int; - fn af_alloc_host(ptr: *mut *const c_void, bytes: dim_t) -> c_int; - fn af_free_host(ptr: *mut c_void) -> c_int; -} - -/// Get size, in bytes, of the arrayfire native type -pub fn get_size(value: DType) -> usize { - let mut ret_val: usize = 0; - let err_val = unsafe { af_get_size_of(&mut ret_val as *mut size_t, value as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - ret_val -} - -/// Allocates space using Arrayfire allocator in host memory -pub fn alloc_host(elements: usize, _type: DType) -> *const T { - let ptr: *const T = ::std::ptr::null(); - let bytes = (elements * get_size(_type)) as dim_t; - - let err_val = unsafe { af_alloc_host(&mut (ptr as *const c_void), bytes) }; - HANDLE_ERROR(AfError::from(err_val)); - - ptr -} - -/// Frees memory allocated by Arrayfire allocator in host memory -pub fn free_host(ptr: *mut T) { - let err_val = unsafe { af_free_host(ptr as *mut c_void) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -impl From for AfError { - fn from(t: i32) -> Self { - assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32); - unsafe { mem::transmute(t) } - } -} - -impl From for DType { - fn from(t: u32) -> Self { - assert!(DType::F32 as u32 <= t && t <= DType::U64 as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for InterpType { - fn from(t: u32) -> Self { - assert!(InterpType::NEAREST as u32 <= t && t <= InterpType::BICUBIC_SPLINE as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for ConvMode { - fn from(t: u32) -> Self { - assert!(ConvMode::DEFAULT as u32 <= t && t <= ConvMode::EXPAND as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for ConvDomain { - fn from(t: u32) -> Self { - assert!(ConvDomain::AUTO as u32 <= t && t <= ConvDomain::FREQUENCY as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for MatchType { - fn from(t: u32) -> Self { - assert!(MatchType::SAD as u32 <= t && t <= MatchType::SHD as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for ColorMap { - fn from(t: u32) -> Self { - assert!(ColorMap::DEFAULT as u32 <= t && t <= ColorMap::BLUE as u32); - unsafe { mem::transmute(t) } - } -} - -mod private { - pub trait Sealed: std::fmt::Debug + std::marker::Copy + std::default::Default {} - - impl Sealed for num::complex::Complex {} - impl Sealed for num::complex::Complex {} - impl Sealed for f32 {} - impl Sealed for f64 {} - impl Sealed for bool {} - impl Sealed for u8 {} - impl Sealed for i16 {} - impl Sealed for u16 {} - impl Sealed for half::f16 {} - impl Sealed for i32 {} - impl Sealed for u32 {} - impl Sealed for i64 {} - impl Sealed for u64 {} - impl Sealed for usize {} -} - -/// Types of the data that can be generated using ArrayFire data generation functions. -/// -/// The trait HasAfEnum has been defined internally for the following types. We strongly suggest -/// not to implement this trait in your program for user defined types because ArrayFire functions -/// will only work for the following data types currently. Any such trait implementation for types -/// other than the ones listed below will result in undefined behavior. -/// -/// - f32 -/// - f64 -/// - num::Complex\ -/// - num::Complex\ -/// - bool -/// - i32 -/// - u32 -/// - u8 -/// - i64 -/// - u64 -/// - i16 -/// - u16 -/// -pub trait HasAfEnum: private::Sealed { - /// This type alias points to `Self` always. - type InType: HasAfEnum; - /// This type alias points to the data type used to hold real part of a - /// complex number. For real valued numbers, this points to `Self`. - type BaseType: HasAfEnum; - /// This type alias points to `f32` for all 32 bit size types and `f64` for - /// larger 64-bit size types. - type AbsOutType: HasAfEnum; - /// This type alias points to `f64`/`f32` for floating point types and - /// `Self` otherwise. - type ArgOutType: HasAfEnum; - /// This type alias is used to define the output Array type for unary - /// operations. It points to `Self` for floating point types, either - /// real or complex. It points to `f32` for rest of the input types. - type UnaryOutType: HasAfEnum; - /// This type alias points to complex type created from a given input type. - /// This alias always points to either `std::Complex` or `std::Complex` - type ComplexOutType; - /// This type alias points to a data type that can store the mean value for - /// a given input type. This alias points to `f32`/`Complex` for all 32 - /// bit size types and `f64`/`Complex` for larger 64-bit size types. - type MeanOutType: HasAfEnum; - /// This type alias points to a data type that can store the result of - /// aggregation of set of values for a given input type. Aggregate type - /// alias points to below types for given input types: - /// - `Self` for input types: `Complex<64>`, `Complex`, `f64`, `f32`, `i64`, `u64` - /// - `u32` for input types: `bool` - /// - `u32` for input types: `u8` - /// - `i32` for input types: `i16` - /// - `u32` for input types: `u16` - /// - `i32` for input types: `i32` - /// - `u32` for input types: `u32` - type AggregateOutType: HasAfEnum; - /// This type is different for b8 input type - type ProductOutType: HasAfEnum; - /// This type alias points to the output type for given input type of - /// sobel filter operation. Sobel filter output alias points to below - /// types for given input types: - /// - `f32` for input types: `Complex`, `f32` - /// - `f64` for input types: `Complex`, `f64` - /// - `i32` for input types: `bool`, `u8`, `i16`, `u16`, `i32`, `u32` - /// - `i64` for input types: `i64`, `u64` - type SobelOutType: HasAfEnum; - - /// Return trait implmentors corresponding [DType](./enum.DType.html) - fn get_af_dtype() -> DType; -} - -impl HasAfEnum for Complex { - type InType = Self; - type BaseType = f32; - type AbsOutType = f32; - type ArgOutType = f32; - type UnaryOutType = Self; - type ComplexOutType = Self; - type MeanOutType = Self; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = Self; - - fn get_af_dtype() -> DType { - DType::C32 - } -} -impl HasAfEnum for Complex { - type InType = Self; - type BaseType = f64; - type AbsOutType = f64; - type ArgOutType = f64; - type UnaryOutType = Self; - type ComplexOutType = Self; - type MeanOutType = Self; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = Self; - - fn get_af_dtype() -> DType { - DType::C64 - } -} -impl HasAfEnum for f32 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = f32; - type UnaryOutType = Self; - type ComplexOutType = Complex; - type MeanOutType = Self; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = Self; - - fn get_af_dtype() -> DType { - DType::F32 - } -} -impl HasAfEnum for f64 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f64; - type ArgOutType = f64; - type UnaryOutType = Self; - type ComplexOutType = Complex; - type MeanOutType = Self; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = Self; - - fn get_af_dtype() -> DType { - DType::F64 - } -} -impl HasAfEnum for bool { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = bool; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = u32; - type ProductOutType = bool; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::B8 - } -} -impl HasAfEnum for u8 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = u8; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = u32; - type ProductOutType = u32; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::U8 - } -} -impl HasAfEnum for i16 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = i16; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = i32; - type ProductOutType = i32; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::S16 - } -} -impl HasAfEnum for u16 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = u16; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = u32; - type ProductOutType = u32; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::U16 - } -} -impl HasAfEnum for f16 { - type InType = Self; - type BaseType = Self; - type AbsOutType = Self; - type ArgOutType = Self; - type UnaryOutType = Self; - type ComplexOutType = Complex; - type MeanOutType = Self; - type AggregateOutType = f32; - type ProductOutType = f32; - type SobelOutType = Self; - - fn get_af_dtype() -> DType { - DType::F16 - } -} -impl HasAfEnum for i32 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = i32; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = i32; - type ProductOutType = i32; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::S32 - } -} -impl HasAfEnum for u32 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f32; - type ArgOutType = u32; - type UnaryOutType = f32; - type ComplexOutType = Complex; - type MeanOutType = f32; - type AggregateOutType = u32; - type ProductOutType = u32; - type SobelOutType = i32; - - fn get_af_dtype() -> DType { - DType::U32 - } -} -impl HasAfEnum for i64 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f64; - type ArgOutType = i64; - type UnaryOutType = f64; - type ComplexOutType = Complex; - type MeanOutType = f64; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = i64; - - fn get_af_dtype() -> DType { - DType::S64 - } -} -impl HasAfEnum for u64 { - type InType = Self; - type BaseType = Self; - type AbsOutType = f64; - type ArgOutType = u64; - type UnaryOutType = f64; - type ComplexOutType = Complex; - type MeanOutType = f64; - type AggregateOutType = Self; - type ProductOutType = Self; - type SobelOutType = i64; - - fn get_af_dtype() -> DType { - DType::U64 - } -} - -impl From for SparseFormat { - fn from(t: u32) -> Self { - assert!(SparseFormat::DENSE as u32 <= t && t <= SparseFormat::COO as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for BinaryOp { - fn from(t: u32) -> Self { - assert!(BinaryOp::ADD as u32 <= t && t <= BinaryOp::MAX as u32); - unsafe { mem::transmute(t) } - } -} - -impl From for RandomEngineType { - fn from(t: u32) -> Self { - assert!( - RandomEngineType::PHILOX_4X32_10 as u32 <= t - && t <= RandomEngineType::MERSENNE_GP11213 as u32 - ); - unsafe { mem::transmute(t) } - } -} - -/// This is an internal trait defined and implemented by ArrayFire -/// create for rust's built-in types to figure out the data type -/// binary operation's results. -pub trait ImplicitPromote: HasAfEnum { - /// This type alias points to the type of the result obtained - /// by performing a given binary option on given type and `RHS`. - type Output: HasAfEnum; -} - -impl ImplicitPromote for T -where - T: HasAfEnum, -{ - type Output = T; -} - -macro_rules! implicit { - [$implType: ident, $rhsType: ident => $outType: ident] => ( - impl ImplicitPromote< $rhsType > for $implType { - type Output = $outType; - } - ) -} - -// -//implicit(implementation type, RHS type, output type) -// - -//LHS is Complex double -implicit!(c64, c32 => c64); -implicit!(c64, f64 => c64); -implicit!(c64, f32 => c64); -implicit!(c64, f16 => c64); -implicit!(c64, i64 => c64); -implicit!(c64, u64 => c64); -implicit!(c64, i32 => c64); -implicit!(c64, u32 => c64); -implicit!(c64, i16 => c64); -implicit!(c64, u16 => c64); -implicit!(c64, bool => c64); -implicit!(c64, u8 => c64); - -//LHS is Complex float -implicit!(c32, c64 => c64); -implicit!(c32, f64 => c64); -implicit!(c32, f32 => c32); -implicit!(c32, f16 => c32); -implicit!(c32, i64 => c32); -implicit!(c32, u64 => c32); -implicit!(c32, i32 => c32); -implicit!(c32, u32 => c32); -implicit!(c32, i16 => c32); -implicit!(c32, u16 => c32); -implicit!(c32, bool => c32); -implicit!(c32, u8 => c32); - -//LHS is 64-bit floating point -implicit!(f64, c64 => c64); -implicit!(f64, c32 => c64); -implicit!(f64, f32 => f64); -implicit!(f64, f16 => f64); -implicit!(f64, i64 => f64); -implicit!(f64, u64 => f64); -implicit!(f64, i32 => f64); -implicit!(f64, u32 => f64); -implicit!(f64, i16 => f64); -implicit!(f64, u16 => f64); -implicit!(f64, bool => f64); -implicit!(f64, u8 => f64); - -//LHS is 32-bit floating point -implicit!(f32, c64 => c64); -implicit!(f32, c32 => c32); -implicit!(f32, f64 => f64); -implicit!(f32, f16 => f32); -implicit!(f32, i64 => f32); -implicit!(f32, u64 => f32); -implicit!(f32, i32 => f32); -implicit!(f32, u32 => f32); -implicit!(f32, i16 => f32); -implicit!(f32, u16 => f32); -implicit!(f32, bool => f32); -implicit!(f32, u8 => f32); - -//LHS is 16-bit floating point -implicit!(f16, c64 => c64); -implicit!(f16, c32 => c32); -implicit!(f16, f64 => f64); -implicit!(f16, f32 => f32); -implicit!(f16, i64 => f16); -implicit!(f16, u64 => f16); -implicit!(f16, i32 => f16); -implicit!(f16, u32 => f16); -implicit!(f16, i16 => f16); -implicit!(f16, u16 => f16); -implicit!(f16, bool => f16); -implicit!(f16, u8 => f16); - -//LHS is 64-bit signed integer -implicit!(i64, c64 => c64); -implicit!(i64, c32 => c32); -implicit!(i64, f64 => f64); -implicit!(i64, f32 => f32); -implicit!(i64, f16 => f16); -implicit!(i64, u64 => u64); -implicit!(i64, i32 => i64); -implicit!(i64, u32 => i64); -implicit!(i64, i16 => i64); -implicit!(i64, u16 => i64); -implicit!(i64, bool => i64); -implicit!(i64, u8 => i64); - -//LHS is 64-bit unsigned integer -implicit!(u64, c64 => c64); -implicit!(u64, c32 => c32); -implicit!(u64, f64 => f64); -implicit!(u64, f32 => f32); -implicit!(u64, f16 => f16); -implicit!(u64, i64 => u64); -implicit!(u64, i32 => u64); -implicit!(u64, u32 => u64); -implicit!(u64, i16 => u64); -implicit!(u64, u16 => u64); -implicit!(u64, bool => u64); -implicit!(u64, u8 => u64); - -//LHS is 32-bit signed integer -implicit!(i32, c64 => c64); -implicit!(i32, c32 => c32); -implicit!(i32, f64 => f64); -implicit!(i32, f32 => f32); -implicit!(i32, f16 => f16); -implicit!(i32, i64 => i64); -implicit!(i32, u64 => u64); -implicit!(i32, u32 => u32); -implicit!(i32, i16 => i32); -implicit!(i32, u16 => i32); -implicit!(i32, bool => i32); -implicit!(i32, u8 => i32); - -//LHS is 32-bit unsigned integer -implicit!(u32, c64 => c64); -implicit!(u32, c32 => c32); -implicit!(u32, f64 => f64); -implicit!(u32, f32 => f32); -implicit!(u32, f16 => f16); -implicit!(u32, i64 => i64); -implicit!(u32, u64 => u64); -implicit!(u32, i32 => u32); -implicit!(u32, i16 => u32); -implicit!(u32, u16 => u32); -implicit!(u32, bool => u32); -implicit!(u32, u8 => u32); - -//LHS is 16-bit signed integer -implicit!(i16, c64 => c64); -implicit!(i16, c32 => c32); -implicit!(i16, f64 => f64); -implicit!(i16, f32 => f32); -implicit!(i16, f16 => f16); -implicit!(i16, i64 => i64); -implicit!(i16, u64 => u64); -implicit!(i16, i32 => i32); -implicit!(i16, u32 => u32); -implicit!(i16, u16 => u16); -implicit!(i16, bool => u16); -implicit!(i16, u8 => u16); - -//LHS is 16-bit unsigned integer -implicit!(u16, c64 => c64); -implicit!(u16, c32 => c32); -implicit!(u16, f64 => f64); -implicit!(u16, f32 => f32); -implicit!(u16, f16 => f16); -implicit!(u16, i64 => i64); -implicit!(u16, u64 => u64); -implicit!(u16, i32 => i32); -implicit!(u16, u32 => u32); -implicit!(u16, i16 => u16); -implicit!(u16, bool => u16); -implicit!(u16, u8 => u16); - -//LHS is 8-bit unsigned integer -implicit!(u8, c64 => c64); -implicit!(u8, c32 => c32); -implicit!(u8, f64 => f64); -implicit!(u8, f32 => f32); -implicit!(u8, f16 => f16); -implicit!(u8, i64 => i64); -implicit!(u8, u64 => u64); -implicit!(u8, i32 => i32); -implicit!(u8, u32 => u32); -implicit!(u8, i16 => i16); -implicit!(u8, u16 => u16); -implicit!(u8, bool => u8); - -//LHS is bool(af::s8) -implicit!(bool, c64 => c64); -implicit!(bool, c32 => c32); -implicit!(bool, f64 => f64); -implicit!(bool, f32 => f32); -implicit!(bool, f16 => f16); -implicit!(bool, i64 => i64); -implicit!(bool, u64 => u64); -implicit!(bool, i32 => i32); -implicit!(bool, u32 => u32); -implicit!(bool, i16 => i16); -implicit!(bool, u16 => u16); -implicit!(bool, u8 => u8); - -///Trait qualifier to accept either real or complex typed data -pub trait FloatingPoint: HasAfEnum { - /// Use to check if trait implementor is real number - fn is_real() -> bool { - false - } - /// Use to check if trait implementor is complex number - fn is_complex() -> bool { - false - } -} - -impl FloatingPoint for Complex { - fn is_complex() -> bool { - true - } -} -impl FloatingPoint for Complex { - fn is_complex() -> bool { - true - } -} -impl FloatingPoint for f64 { - fn is_real() -> bool { - true - } -} -impl FloatingPoint for f32 { - fn is_real() -> bool { - true - } -} -impl FloatingPoint for f16 { - fn is_real() -> bool { - true - } -} - -///Trait qualifier to accept real data(numbers) -pub trait RealFloating: HasAfEnum {} - -impl RealFloating for f64 {} -impl RealFloating for f32 {} -impl RealFloating for f16 {} - -///Trait qualifier to accept complex data(numbers) -pub trait ComplexFloating: HasAfEnum {} - -impl ComplexFloating for c64 {} -impl ComplexFloating for c32 {} - -///Trait qualifier indicating it can hold real numbers only -pub trait RealNumber: HasAfEnum {} - -impl RealNumber for f64 {} -impl RealNumber for f32 {} -impl RealNumber for f16 {} -impl RealNumber for i32 {} -impl RealNumber for u32 {} -impl RealNumber for i16 {} -impl RealNumber for u16 {} -impl RealNumber for u8 {} -impl RealNumber for bool {} -impl RealNumber for u64 {} -impl RealNumber for i64 {} - -///Trait qualifier for the type of Arrays accepted by scan operations -pub trait Scanable: HasAfEnum {} - -impl Scanable for i32 {} -impl Scanable for u32 {} -impl Scanable for u64 {} -impl Scanable for i64 {} - -/// Trait qualifier for type of Array's that are accepted -/// by native image load/save functions. -pub trait ImageNativeType: HasAfEnum {} - -impl ImageNativeType for f32 {} -impl ImageNativeType for u16 {} -impl ImageNativeType for u8 {} - -/// Trait qualifier for type of Array's that are accepted -/// by image processing functions especially filtering algorithms -pub trait ImageFilterType: HasAfEnum {} - -impl ImageFilterType for f64 {} -impl ImageFilterType for f32 {} -impl ImageFilterType for i32 {} -impl ImageFilterType for u32 {} -impl ImageFilterType for i16 {} -impl ImageFilterType for u16 {} -impl ImageFilterType for u8 {} -impl ImageFilterType for bool {} - -// TODO Rust haven't stabilized trait aliases yet -/// Trait qualifier for given type indicating conversion capability between -/// grayscale and RGB triplets of data -pub trait GrayRGBConvertible: HasAfEnum {} - -impl GrayRGBConvertible for f64 {} -impl GrayRGBConvertible for f32 {} -impl GrayRGBConvertible for i32 {} -impl GrayRGBConvertible for u32 {} -impl GrayRGBConvertible for i16 {} -impl GrayRGBConvertible for u16 {} -impl GrayRGBConvertible for u8 {} - -// TODO Rust haven't stabilized trait aliases yet -/// Trait qualifier for given type indicating computability of Moments -pub trait MomentsComputable: HasAfEnum {} - -impl MomentsComputable for f64 {} -impl MomentsComputable for f32 {} -impl MomentsComputable for i32 {} -impl MomentsComputable for u32 {} -impl MomentsComputable for i16 {} -impl MomentsComputable for u16 {} -impl MomentsComputable for u8 {} - -// TODO Rust haven't stabilized trait aliases yet -/// Trait qualifier for given type indicating computability of Median -pub trait MedianComputable: HasAfEnum {} - -impl MedianComputable for f64 {} -impl MedianComputable for f32 {} -impl MedianComputable for i32 {} -impl MedianComputable for u32 {} -impl MedianComputable for i16 {} -impl MedianComputable for u16 {} -impl MedianComputable for u8 {} - -// TODO Rust haven't stabilized trait aliases yet -/// Trait qualifier for given type indicating if edge calculations such as -/// derivates etc. can be performed -pub trait EdgeComputable: HasAfEnum {} - -impl EdgeComputable for f64 {} -impl EdgeComputable for f32 {} -impl EdgeComputable for i32 {} -impl EdgeComputable for u32 {} -impl EdgeComputable for i16 {} -impl EdgeComputable for u16 {} -impl EdgeComputable for u8 {} - -/// Trait qualifier for given type indicating computability of covariance -pub trait CovarianceComputable: HasAfEnum {} - -impl CovarianceComputable for f64 {} -impl CovarianceComputable for f32 {} -impl CovarianceComputable for i32 {} -impl CovarianceComputable for u32 {} -impl CovarianceComputable for i16 {} -impl CovarianceComputable for u16 {} -impl CovarianceComputable for u8 {} -impl CovarianceComputable for u64 {} -impl CovarianceComputable for i64 {} - -/// Trait qualifier for confidence connected components input -pub trait ConfidenceCCInput: HasAfEnum {} - -impl ConfidenceCCInput for f32 {} -impl ConfidenceCCInput for u32 {} -impl ConfidenceCCInput for u16 {} -impl ConfidenceCCInput for u8 {} - -/// Trait qualifier for confidence connected components input -pub trait DeconvInput: HasAfEnum {} - -impl DeconvInput for f32 {} -impl DeconvInput for i16 {} -impl DeconvInput for u16 {} -impl DeconvInput for u8 {} - -/// Trait qualifier for Reduction Key type -pub trait ReduceByKeyInput: HasAfEnum {} - -impl ReduceByKeyInput for i32 {} -impl ReduceByKeyInput for u32 {} - -impl From for MatProp { - fn from(t: u32) -> Self { - unsafe { mem::transmute(t) } - } -} - -impl BitOr for MatProp { - type Output = Self; - - fn bitor(self, rhs: Self) -> Self { - Self::from(self as u32 | rhs as u32) - } -} - -/// Trait to convert reduction's scalar output to appropriate output type -/// -/// This is an internal trait and ideally of no use to user usecases. -pub trait Fromf64: private::Sealed { - /// Convert to target type from a double precision value - fn fromf64(value: f64) -> Self; -} - -#[rustfmt::skip] -impl Fromf64 for usize{ fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for f64 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for u64 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for i64 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for f32 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for u32 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for i32 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for f16 { fn fromf64(value: f64) -> Self { f16::from_f64(value) }} -#[rustfmt::skip] -impl Fromf64 for u16 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for i16 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for u8 { fn fromf64(value: f64) -> Self { value as Self }} -#[rustfmt::skip] -impl Fromf64 for bool { fn fromf64(value: f64) -> Self { value > 0.0 }} - -///Trait qualifier for the type of Arrays accepted by scan operations -pub trait IndexableType: HasAfEnum {} - -impl IndexableType for f64 {} -impl IndexableType for i64 {} -impl IndexableType for u64 {} -impl IndexableType for f32 {} -impl IndexableType for i32 {} -impl IndexableType for u32 {} -impl IndexableType for f16 {} -impl IndexableType for i16 {} -impl IndexableType for u16 {} -impl IndexableType for u8 {} - -/// Trait qualifier for given type indicating computability of covariance -pub trait IntegralType: HasAfEnum {} - -impl IntegralType for i64 {} -impl IntegralType for u64 {} -impl IntegralType for i32 {} -impl IntegralType for u32 {} -impl IntegralType for i16 {} -impl IntegralType for u16 {} -impl IntegralType for u8 {} -impl IntegralType for bool {} diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs deleted file mode 100644 index 64777e7fa..000000000 --- a/src/graphics/mod.rs +++ /dev/null @@ -1,1024 +0,0 @@ -use super::core::{ - af_array, af_window, AfError, Array, ColorMap, HasAfEnum, MarkerType, HANDLE_ERROR, -}; - -use libc::{c_char, c_double, c_float, c_int, c_uint}; -use std::ffi::CString; -use std::ptr; - -/// Represents a sub-view of Window -/// -/// This struct is used in conjunction with [Window](./struct.Window.html) in multiview -/// mode to render multiple targets to sub-regions of a given window. -/// -#[repr(C)] -struct af_cell { - pub row: c_int, - pub col: c_int, - pub title: *const c_char, - pub cmap: c_uint, -} - -extern "C" { - fn af_create_window(out: *mut af_window, w: c_int, h: c_int, title: *const c_char) -> c_int; - - fn af_set_position(wnd: af_window, x: c_uint, y: c_uint) -> c_int; - fn af_set_title(wnd: af_window, title: *const c_char) -> c_int; - fn af_set_size(wnd: af_window, w: c_uint, h: c_uint) -> c_int; - fn af_set_visibility(wnd: af_window, is_visible: bool) -> c_int; - - fn af_set_axes_titles( - wnd: af_window, - xtitle: *const c_char, - ytitle: *const c_char, - ztitle: *const c_char, - props: *const af_cell, - ) -> c_int; - fn af_set_axes_label_format( - wnd: af_window, - xformat: *const c_char, - yformat: *const c_char, - zformat: *const c_char, - props: *const af_cell, - ) -> c_int; - fn af_set_axes_limits_compute( - wnd: af_window, - x: af_array, - y: af_array, - z: af_array, - exact: bool, - props: *const af_cell, - ) -> c_int; - fn af_set_axes_limits_2d( - wnd: af_window, - xmin: c_float, - xmax: c_float, - ymin: c_float, - ymax: c_float, - exact: bool, - props: *const af_cell, - ) -> c_int; - fn af_set_axes_limits_3d( - wnd: af_window, - xmin: c_float, - xmax: c_float, - ymin: c_float, - ymax: c_float, - zmin: c_float, - zmax: c_float, - exact: bool, - props: *const af_cell, - ) -> c_int; - - fn af_draw_image(wnd: af_window, arr: af_array, props: *const af_cell) -> c_int; - fn af_draw_hist( - wnd: af_window, - x: af_array, - minval: c_double, - maxval: c_double, - props: *const af_cell, - ) -> c_int; - fn af_draw_surface( - wnd: af_window, - xvals: af_array, - yvals: af_array, - S: af_array, - props: *const af_cell, - ) -> c_int; - - fn af_draw_plot_2d(wnd: af_window, x: af_array, y: af_array, props: *const af_cell) -> c_int; - fn af_draw_plot_3d( - wnd: af_window, - x: af_array, - y: af_array, - z: af_array, - props: *const af_cell, - ) -> c_int; - fn af_draw_plot_nd(wnd: af_window, P: af_array, props: *const af_cell) -> c_int; - - fn af_draw_scatter_2d( - wnd: af_window, - x: af_array, - y: af_array, - marker: c_uint, - props: *const af_cell, - ) -> c_int; - fn af_draw_scatter_3d( - wnd: af_window, - x: af_array, - y: af_array, - z: af_array, - marker: c_uint, - props: *const af_cell, - ) -> c_int; - fn af_draw_scatter_nd( - wnd: af_window, - P: af_array, - marker: c_uint, - props: *const af_cell, - ) -> c_int; - - fn af_draw_vector_field_2d( - wnd: af_window, - xpnts: af_array, - ypnts: af_array, - xdirs: af_array, - ydirs: af_array, - props: *const af_cell, - ) -> c_int; - fn af_draw_vector_field_3d( - wnd: af_window, - xpnts: af_array, - ypnts: af_array, - xdirs: af_array, - ydirs: af_array, - zdirs: af_array, - zdirs: af_array, - props: *const af_cell, - ) -> c_int; - fn af_draw_vector_field_nd( - wnd: af_window, - pnts: af_array, - dirs: af_array, - props: *const af_cell, - ) -> c_int; - - fn af_grid(wnd: af_window, rows: c_int, cols: c_int) -> c_int; - fn af_show(wnd: af_window) -> c_int; - fn af_is_window_closed(out: *mut bool, wnd: af_window) -> c_int; - fn af_destroy_window(wnd: af_window) -> c_int; -} - -/// Used to render [Array](./struct.Array.html) objects -/// -/// The renderings can be either plots, histograms or simply just image displays. -/// A single window can also display multiple of the above renderings at the same time, which -/// is known as multiview mode. An example of that is given below. -/// -/// # Examples -/// -/// ```rust,no_run -/// use arrayfire::{histogram, load_image, Window}; -/// let mut wnd = Window::new(1280, 720, String::from("Image Histogram")); -/// let img = load_image::("Path to image".to_string(), true/*If color image, 'false' otherwise*/); -/// let hst = histogram(&img, 256, 0 as f64, 255 as f64); -/// -/// loop { -/// wnd.grid(2, 1); -/// -/// wnd.set_view(0, 0); -/// wnd.draw_image(&img, Some("Input Image".to_string())); -/// -/// wnd.set_view(1, 0); -/// wnd.draw_hist(&hst, 0.0, 255.0, Some("Input Image Histogram".to_string())); -/// -/// wnd.show(); -/// -/// if wnd.is_closed() == true { break; } -/// } -/// ``` -#[derive(Clone)] -pub struct Window { - handle: af_window, - row: i32, - col: i32, - cmap: ColorMap, -} - -impl Drop for Window { - fn drop(&mut self) { - let err_val = unsafe { af_destroy_window(self.handle) }; - match err_val { - 0 => (), - _ => panic!( - "Window object destruction failed with error code: {}", - err_val - ), - } - } -} - -impl Window { - /// Creates new Window object - /// - /// # Parameters - /// - /// - `width` is width of the window - /// - `height` is the height of window - /// - `title` is the string displayed on window title bar - /// - /// # Return Values - /// - /// Window Object - #[allow(clippy::match_wild_err_arm)] - pub fn new(width: i32, height: i32, title: String) -> Self { - let cstr_ret = CString::new(title); - match cstr_ret { - Ok(cstr) => { - let mut temp: af_window = std::ptr::null_mut(); - let err_val = unsafe { - af_create_window(&mut temp as *mut af_window, width, height, cstr.as_ptr()) - }; - HANDLE_ERROR(AfError::from(err_val)); - Window { - handle: temp, - row: -1, - col: -1, - cmap: ColorMap::DEFAULT, - } - } - Err(_) => { - panic!("String creation failed while prepping params for window creation.") - } - } - } - - /// Set window starting position on the screen - /// - /// # Parameters - /// - /// - `x` is the horiontal coordinate where window is to be placed - /// - `y` is the vertical coordinate where window is to be placed - pub fn set_position(&self, x: u32, y: u32) { - let err_val = unsafe { af_set_position(self.handle, x, y) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set window title - /// - /// # Parameters - /// - /// - `title` is the string to be displayed on window title bar - pub fn set_title(&self, title: String) { - let cstr_ret = CString::new(title); - match cstr_ret { - Ok(cstr) => { - let err_val = unsafe { af_set_title(self.handle, cstr.as_ptr()) }; - HANDLE_ERROR(AfError::from(err_val)); - } - Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL), - } - } - - /// Set window visibility - /// - /// # Parameters - /// - /// - `is_visible` is a boolean indicating whether window is to be hidden or brought into focus - /// - /// # Return Values - /// - /// None - pub fn set_visibility(&self, is_visible: bool) { - let err_val = unsafe { af_set_visibility(self.handle, is_visible) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set window size - /// - /// # Parameters - /// - /// - `w` is the target width of window - /// - `h` is the target height of window - pub fn set_size(&self, w: u32, h: u32) { - let err_val = unsafe { af_set_size(self.handle, w, h) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set color map to be used for rendering image, it can take one of the values of enum - /// [ColorMap](./enum.ColorMap.html) - pub fn set_colormap(&mut self, cmap: ColorMap) { - self.cmap = cmap; - } - - /// Returns true if the window close is triggered by the user - pub fn is_closed(&self) -> bool { - let mut temp: bool = true; - let err_val = unsafe { af_is_window_closed(&mut temp as *mut bool, self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - temp - } - - /// Setup display layout in multiview mode - /// - /// # Parameters - /// - /// - `rows` is the number of rows into which whole window is split into in multiple view mode - /// - `cols` is the number of cols into which whole window is split into in multiple view mode - pub fn grid(&self, rows: i32, cols: i32) { - let err_val = unsafe { af_grid(self.handle, rows, cols) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Used in multiview mode to swap back buffer with front buffer to show the recently rendered - /// frame - pub fn show(&mut self) { - let err_val = unsafe { af_show(self.handle) }; - HANDLE_ERROR(AfError::from(err_val)); - self.row = -1; - self.col = -1; - } - - /// Set the current sub-region to render - /// - /// This function is only to be used into multiview mode - /// - /// # Parameters - /// - /// - `r` is the target row id - /// - `c` is the target row id - pub fn set_view(&mut self, r: i32, c: i32) { - self.row = r; - self.col = c; - } - - /// Set chart axes titles - /// - /// # Parameters - /// - /// - `xlabel` is x axis title - /// - `ylabel` is y axis title - /// - `zlabel` is z axis title - pub fn set_axes_titles(&mut self, xlabel: String, ylabel: String, zlabel: String) { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - let xstr = CString::new(xlabel).unwrap(); - let ystr = CString::new(ylabel).unwrap(); - let zstr = CString::new(zlabel).unwrap(); - - let err_val = unsafe { - af_set_axes_titles( - self.handle, - xstr.as_ptr(), - ystr.as_ptr(), - zstr.as_ptr(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set chart axes labels format - /// - /// # Parameters - /// - /// - `xlabel_format` is x axis label format. format specific is identical to C's printf format - /// - `ylabel_format` is y axis label format. format specific is identical to C's printf format - /// - `zlabel_format` is z axis label format. format specific is identical to C's printf format - pub fn set_axes_label_format( - &mut self, - xlabel_format: String, - ylabel_format: String, - zlabel_format: String, - ) { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - let xstr = CString::new(xlabel_format).unwrap(); - let ystr = CString::new(ylabel_format).unwrap(); - let zstr = CString::new(zlabel_format).unwrap(); - - let err_val = unsafe { - af_set_axes_label_format( - self.handle, - xstr.as_ptr(), - ystr.as_ptr(), - zstr.as_ptr(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set chart axes labels formats - /// - /// Axes labels use printf style format specifiers. Default specifier for the data displayed - /// as labels is %4.1f. This function lets the user change this label formatting to whichever - /// format that fits their data range and precision. - /// - /// # Parameters - /// - /// - `xlabel` is printf style format specifier for x axis - /// - `ylabel` is printf style format specifier for y axis - /// - `zlabel` is printf style format specifier for z axis - pub fn set_axes_label_formats(&mut self, xformat: String, yformat: String, zformat: String) { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - let xstr = CString::new(xformat).unwrap(); - let ystr = CString::new(yformat).unwrap(); - let zstr = CString::new(zformat).unwrap(); - - let err_val = unsafe { - af_set_axes_titles( - self.handle, - xstr.as_ptr(), - ystr.as_ptr(), - zstr.as_ptr(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set chart axes limits by computing limits from data - /// - /// In multiple view (grid) mode, setting limits will effect the chart that is currently - /// active via set_view call - /// - /// # Parameters - /// - /// - `xrange` is set of all x values to compute min/max for x axis - /// - `yrange` is set of all y values to compute min/max for y axis - /// - `zrange` is set of all z values to compute min/max for z axis. If None is passed to - /// this paramter, 2d chart limits are set. - /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange` - /// are to extracted. If exact is false then the most significant digit is rounded up - /// to next power of 2 and the magnitude remains the same. - pub fn set_axes_limits_compute( - &mut self, - xrange: &Array, - yrange: &Array, - zrange: Option<&Array>, - exact: bool, - ) where - T: HasAfEnum, - { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_set_axes_limits_compute( - self.handle, - xrange.get(), - yrange.get(), - match zrange { - Some(z) => z.get(), - None => std::ptr::null_mut(), - }, - exact, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set 2d chart axes limits - /// - /// In multiple view (grid) mode, setting limits will effect the chart that is currently - /// active via set_view call - /// - /// # Parameters - /// - /// - `xmin` is minimum value on x axis - /// - `xmax` is maximum value on x axis - /// - `ymin` is minimum value on y axis - /// - `ymax` is maximum value on y axis - /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange` - /// are to extracted. If exact is false then the most significant digit is rounded up - /// to next power of 2 and the magnitude remains the same. - pub fn set_axes_limits_2d(&mut self, xmin: f32, xmax: f32, ymin: f32, ymax: f32, exact: bool) { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_set_axes_limits_2d( - self.handle, - xmin, - xmax, - ymin, - ymax, - exact, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Set 3d chart axes limits - /// - /// In multiple view (grid) mode, setting limits will effect the chart that is currently - /// active via set_view call - /// - /// # Parameters - /// - /// - `xmin` is minimum value on x axis - /// - `xmax` is maximum value on x axis - /// - `ymin` is minimum value on y axis - /// - `ymax` is maximum value on y axis - /// - `zmin` is minimum value on z axis - /// - `zmax` is maximum value on z axis - /// - `exact` indicates if the exact min/max values from `xrange`, `yrange` and `zrange` - /// are to extracted. If exact is false then the most significant digit is rounded up - /// to next power of 2 and the magnitude remains the same. - #[allow(clippy::too_many_arguments)] - pub fn set_axes_limits_3d( - &mut self, - xmin: f32, - xmax: f32, - ymin: f32, - ymax: f32, - zmin: f32, - zmax: f32, - exact: bool, - ) { - let cprops = af_cell { - row: self.row, - col: self.col, - title: ptr::null(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_set_axes_limits_3d( - self.handle, - xmin, - xmax, - ymin, - ymax, - zmin, - zmax, - exact, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Array as an image - /// - /// # Parameters - /// - /// - `input` image - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_image(&self, input: &Array, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { af_draw_image(self.handle, input.get(), &cprops as *const af_cell) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given two Array's `x` and `y` as a 2d line plot - /// - /// # Parameters - /// - /// - `x` is the x coordinates of the plot - /// - `y` is the y coordinates of the plot - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_plot2(&self, x: &Array, y: &Array, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = - unsafe { af_draw_plot_2d(self.handle, x.get(), y.get(), &cprops as *const af_cell) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Array's `x`, `y` and `z` as a 3d line plot - /// - /// # Parameters - /// - /// - `x` is the x coordinates of the plot - /// - `y` is the y coordinates of the plot - /// - `z` is the z coordinates of the plot - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_plot3(&self, x: &Array, y: &Array, z: &Array, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_plot_3d( - self.handle, - x.get(), - y.get(), - z.get(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render give Arrays of points as a 3d line plot - /// - /// # Parameters - /// - /// - `points` is an Array containing list of points of plot - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_plot(&self, points: &Array, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = - unsafe { af_draw_plot_nd(self.handle, points.get(), &cprops as *const af_cell) }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Array as a histogram - /// - /// # Parameters - /// - /// - `hst` is an Array containing histogram data - /// - `minval` is the minimum bin value of histogram - /// - `maxval` is the maximum bin value of histogram - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_hist(&self, hst: &Array, minval: f64, maxval: f64, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_hist( - self.handle, - hst.get(), - minval, - maxval, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render give Arrays as 3d surface - /// - /// # Parameters - /// - /// - `x` is the x coordinates of the surface plot - /// - `y` is the y coordinates of the surface plot - /// - `z` is the z coordinates of the surface plot - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_surface( - &self, - xvals: &Array, - yvals: &Array, - zvals: &Array, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_surface( - self.handle, - xvals.get(), - yvals.get(), - zvals.get(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Arrays as 2d scatter plot - /// - /// # Parameters - /// - /// - `xvals` is the x coordinates of the scatter plot - /// - `yvals` is the y coordinates of the scatter plot - /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html) - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_scatter2( - &self, - xvals: &Array, - yvals: &Array, - marker: MarkerType, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_scatter_2d( - self.handle, - xvals.get(), - yvals.get(), - marker as c_uint, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Arrays as 3d scatter plot - /// - /// # Parameters - /// - /// - `xvals` is the x coordinates of the scatter plot - /// - `yvals` is the y coordinates of the scatter plot - /// - `zvals` is the z coordinates of the scatter plot - /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html) - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_scatter3( - &self, - xvals: &Array, - yvals: &Array, - zvals: &Array, - marker: MarkerType, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_scatter_3d( - self.handle, - xvals.get(), - yvals.get(), - zvals.get(), - marker as c_uint, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render give Array as 3d scatter plot - /// - /// # Parameters - /// - /// - `points` is an Array containing list of points of plot - /// - `marker` is of enum type [MarkerType](./enum.MarkerType.html) - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_scatter(&self, vals: &Array, marker: MarkerType, title: Option) - where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_scatter_nd( - self.handle, - vals.get(), - marker as c_uint, - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Arrays as 2d vector field - /// - /// # Parameters - /// - /// - `xpnts` is an Array containing list of x coordinates - /// - `xdirs` is an Array containing direction component of x coord - /// - `ypnts` is an Array containing list of y coordinates - /// - `ydirs` is an Array containing direction component of y coord - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_vector_field2( - &self, - xpnts: &Array, - ypnts: &Array, - xdirs: &Array, - ydirs: &Array, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_vector_field_2d( - self.handle, - xpnts.get(), - ypnts.get(), - xdirs.get(), - ydirs.get(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Arrays as 3d vector field - /// - /// # Parameters - /// - /// - `xpnts` is an Array containing list of x coordinates - /// - `xdirs` is an Array containing direction component of x coord - /// - `ypnts` is an Array containing list of y coordinates - /// - `ydirs` is an Array containing direction component of y coord - /// - `zpnts` is an Array containing list of z coordinates - /// - `zdirs` is an Array containing direction component of z coord - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - #[allow(clippy::too_many_arguments)] - pub fn draw_vector_field3( - &self, - xpnts: &Array, - ypnts: &Array, - zpnts: &Array, - xdirs: &Array, - ydirs: &Array, - zdirs: &Array, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_vector_field_3d( - self.handle, - xpnts.get(), - ypnts.get(), - zpnts.get(), - xdirs.get(), - ydirs.get(), - zdirs.get(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } - - /// Render given Array as vector field - /// - /// # Parameters - /// - /// - `points` is an Array containing list of coordinates of vector field - /// - `directions` is an Array containing directions at the coordinates specified in `points` - /// Array. - /// - `title` parameter has effect only in multiview mode, where this string - /// is displayed as the respective cell/view title. - pub fn draw_vector_field( - &self, - points: &Array, - directions: &Array, - title: Option, - ) where - T: HasAfEnum, - { - let tstr = match title { - Some(s) => s, - None => format!("Cell({},{}))", self.col, self.row), - }; - let tstr = CString::new(tstr).unwrap(); - let cprops = af_cell { - row: self.row, - col: self.col, - title: tstr.as_ptr(), - cmap: self.cmap as u32, - }; - - let err_val = unsafe { - af_draw_vector_field_nd( - self.handle, - points.get(), - directions.get(), - &cprops as *const af_cell, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - } -} diff --git a/src/image/mod.rs b/src/image/mod.rs deleted file mode 100644 index 0b0e3ba34..000000000 --- a/src/image/mod.rs +++ /dev/null @@ -1,1887 +0,0 @@ -use super::core::{ - af_array, dim_t, AfError, Array, BorderType, CannyThresholdType, ColorSpace, ConfidenceCCInput, - Connectivity, DeconvInput, DiffusionEq, EdgeComputable, FloatingPoint, FluxFn, - GrayRGBConvertible, HasAfEnum, ImageFilterType, ImageNativeType, InterpType, InverseDeconvAlgo, - IterativeDeconvAlgo, MomentType, MomentsComputable, RealFloating, RealNumber, YCCStd, - HANDLE_ERROR, -}; - -use libc::{c_char, c_double, c_float, c_int, c_uint}; -use std::ffi::CString; - -// unused functions from image.h header -// TODO add later when requested -// af_load_image_memory -// af_save_image_memory -// af_delete_image_memory - -extern "C" { - fn af_cast(out: *mut af_array, arr: af_array, aftype: c_uint) -> c_int; - fn af_gradient(dx: *mut af_array, dy: *mut af_array, arr: af_array) -> c_int; - fn af_load_image(out: *mut af_array, filename: *const c_char, iscolor: bool) -> c_int; - fn af_save_image(filename: *const c_char, input: af_array) -> c_int; - fn af_load_image_native(out: *mut af_array, filename: *const c_char) -> c_int; - fn af_save_image_native(filename: *const c_char, input: af_array) -> c_int; - - fn af_resize( - out: *mut af_array, - input: af_array, - odim0: dim_t, - odim1: dim_t, - method: c_uint, - ) -> c_int; - - fn af_transform( - out: *mut af_array, - input: af_array, - trans: af_array, - odim0: dim_t, - odim1: dim_t, - method: c_uint, - is_inverse: bool, - ) -> c_int; - - fn af_rotate( - out: *mut af_array, - input: af_array, - theta: c_float, - crop: bool, - method: c_uint, - ) -> c_int; - - fn af_translate( - out: *mut af_array, - input: af_array, - trans0: c_float, - trans1: c_float, - odim0: dim_t, - odim1: dim_t, - method: c_uint, - ) -> c_int; - - fn af_scale( - out: *mut af_array, - input: af_array, - scale0: c_float, - scale1: c_float, - odim0: dim_t, - odim1: dim_t, - method: c_uint, - ) -> c_int; - - fn af_skew( - out: *mut af_array, - input: af_array, - skew0: c_float, - skew1: c_float, - odim0: dim_t, - odim1: dim_t, - method: c_uint, - is_inverse: bool, - ) -> c_int; - - fn af_histogram( - out: *mut af_array, - input: af_array, - nbins: c_uint, - minval: c_double, - maxval: c_double, - ) -> c_int; - - fn af_dilate(out: *mut af_array, input: af_array, mask: af_array) -> c_int; - fn af_dilate3(out: *mut af_array, input: af_array, mask: af_array) -> c_int; - fn af_erode(out: *mut af_array, input: af_array, mask: af_array) -> c_int; - fn af_erode3(out: *mut af_array, input: af_array, mask: af_array) -> c_int; - fn af_regions(out: *mut af_array, input: af_array, conn: c_uint, aftype: c_uint) -> c_int; - fn af_sobel_operator(dx: *mut af_array, dy: *mut af_array, i: af_array, ksize: c_uint) - -> c_int; - fn af_rgb2gray( - out: *mut af_array, - input: af_array, - r: c_float, - g: c_float, - b: c_float, - ) -> c_int; - fn af_gray2rgb( - out: *mut af_array, - input: af_array, - r: c_float, - g: c_float, - b: c_float, - ) -> c_int; - fn af_hist_equal(out: *mut af_array, input: af_array, hist: af_array) -> c_int; - fn af_hsv2rgb(out: *mut af_array, input: af_array) -> c_int; - fn af_rgb2hsv(out: *mut af_array, input: af_array) -> c_int; - - fn af_bilateral( - out: *mut af_array, - input: af_array, - sp_sig: c_float, - ch_sig: c_float, - iscolor: bool, - ) -> c_int; - - fn af_mean_shift( - out: *mut af_array, - input: af_array, - sp_sig: c_float, - ch_sig: c_float, - iter: c_uint, - iscolor: bool, - ) -> c_int; - - fn af_medfilt( - out: *mut af_array, - input: af_array, - wlen: dim_t, - wwid: dim_t, - etype: c_uint, - ) -> c_int; - - fn af_medfilt1(out: *mut af_array, input: af_array, wlen: dim_t, etype: c_uint) -> c_int; - - fn af_minfilt( - out: *mut af_array, - input: af_array, - wlen: dim_t, - wwid: dim_t, - etype: c_uint, - ) -> c_int; - - fn af_maxfilt( - out: *mut af_array, - input: af_array, - wlen: dim_t, - wwid: dim_t, - etype: c_uint, - ) -> c_int; - - fn af_gaussian_kernel( - out: *mut af_array, - rows: c_int, - cols: c_int, - sigma_r: c_double, - sigma_c: c_double, - ) -> c_int; - - fn af_color_space( - out: *mut af_array, - input: af_array, - tospace: c_uint, - fromspace: c_uint, - ) -> c_int; - - fn af_unwrap( - out: *mut af_array, - input: af_array, - wx: dim_t, - wy: dim_t, - sx: dim_t, - sy: dim_t, - px: dim_t, - py: dim_t, - is_column: bool, - ) -> c_int; - - fn af_wrap( - out: *mut af_array, - input: af_array, - ox: dim_t, - oy: dim_t, - wx: dim_t, - wy: dim_t, - sx: dim_t, - sy: dim_t, - px: dim_t, - py: dim_t, - is_column: bool, - ) -> c_int; - - fn af_sat(out: *mut af_array, input: af_array) -> c_int; - - fn af_ycbcr2rgb(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int; - fn af_rgb2ycbcr(out: *mut af_array, input: af_array, stnd: c_uint) -> c_int; - fn af_is_image_io_available(out: *mut bool) -> c_int; - fn af_transform_coordinates( - out: *mut af_array, - tf: af_array, - d0: c_float, - d1: c_float, - ) -> c_int; - - fn af_moments(out: *mut af_array, input: af_array, moment: c_uint) -> c_int; - fn af_moments_all(out: *mut c_double, input: af_array, moment: c_uint) -> c_int; - - fn af_canny( - out: *mut af_array, - input: af_array, - thres_type: c_int, - low: c_float, - high: c_float, - swindow: c_uint, - is_fast: bool, - ) -> c_int; - fn af_anisotropic_diffusion( - out: *mut af_array, - input: af_array, - dt: c_float, - K: c_float, - iters: c_uint, - fftype: c_uint, - diff_kind: c_uint, - ) -> c_int; - fn af_confidence_cc( - out: *mut af_array, - input: af_array, - seedx: af_array, - seedy: af_array, - radius: c_uint, - multiplier: c_uint, - iterations: c_int, - seg_val: c_double, - ) -> c_int; - fn af_iterative_deconv( - out: *mut af_array, - input: af_array, - ker: af_array, - iterations: c_uint, - rfactor: c_float, - algo: c_uint, - ) -> c_int; - fn af_inverse_deconv( - out: *mut af_array, - input: af_array, - ker: af_array, - gamma: c_float, - algo: c_uint, - ) -> c_int; -} - -/// Calculate the gradients -/// -/// The gradients along the first and second dimensions are calculated simultaneously. -/// -/// # Parameters -/// -/// - `input` is the input Array -/// -/// # Return Values -/// -/// A tuple of Arrays. -/// -/// The first Array is `dx` which is the gradient along the 1st dimension. -/// -/// The second Array is `dy` which is the gradient along the 2nd dimension. -pub fn gradient(input: &Array) -> (Array, Array) -where - T: HasAfEnum + FloatingPoint, -{ - let mut dx: af_array = std::ptr::null_mut(); - let mut dy: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_gradient( - &mut dx as *mut af_array, - &mut dy as *mut af_array, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (dx.into(), dy.into()) -} - -/// Load Image into Array -/// -/// Only, Images with 8/16/32 bits per channel can be loaded using this function. -/// -/// # Parameters -/// -/// - `filename` is aboslute path of the image to be loaded. -/// - `is_color` indicates if the image file at given path is color or gray scale. -/// -/// # Return Arrays -/// -/// An Array with pixel values loaded from the image -#[allow(clippy::match_wild_err_arm)] -pub fn load_image(filename: String, is_color: bool) -> Array -where - T: HasAfEnum + RealNumber, -{ - let cstr_param = match CString::new(filename) { - Ok(cstr) => cstr, - Err(_) => panic!("CString creation from input filename failed"), - }; - let trgt_type = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err1 = unsafe { af_load_image(&mut temp as *mut af_array, cstr_param.as_ptr(), is_color) }; - HANDLE_ERROR(AfError::from(err1)); - - let mut img: af_array = std::ptr::null_mut(); - let err2 = unsafe { af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint) }; - HANDLE_ERROR(AfError::from(err2)); - - img.into() -} - -/// Load Image into Array in it's native type -/// -/// This load image function allows you to load images as U8, U16 or F32 -/// depending on the type of input image as shown by the table below. -/// -/// Bits per Color (Gray/RGB/RGBA Bits Per Pixel) | Array Type | Range -/// -----------------------------------------------|-------------|--------------- -/// 8 ( 8/24/32 BPP) | u8 | 0 - 255 -/// 16 (16/48/64 BPP) | u16 | 0 - 65535 -/// 32 (32/96/128 BPP) | f32 | 0 - 1 -/// -/// # Parameters -/// -/// - `filename` is name of file to be loaded -/// -/// # Return Arrays -/// -/// An Array with pixel values loaded from the image -#[allow(clippy::match_wild_err_arm)] -pub fn load_image_native(filename: String) -> Array -where - T: HasAfEnum + ImageNativeType, -{ - let cstr_param = match CString::new(filename) { - Ok(cstr) => cstr, - Err(_) => panic!("CString creation from input filename failed"), - }; - let trgt_type = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err1 = unsafe { af_load_image_native(&mut temp as *mut af_array, cstr_param.as_ptr()) }; - HANDLE_ERROR(AfError::from(err1)); - - let mut img: af_array = std::ptr::null_mut(); - let err2 = unsafe { af_cast(&mut img as *mut af_array, temp, trgt_type as c_uint) }; - HANDLE_ERROR(AfError::from(err2)); - - img.into() -} - -/// Save an Array to an image file -/// -/// # Parameters -/// -/// - `filename` is the abolute path(includes filename) at which input Array is going to be saved -/// - `input` is the Array to be stored into the image file -#[allow(clippy::match_wild_err_arm)] -pub fn save_image(filename: String, input: &Array) -where - T: HasAfEnum + RealNumber, -{ - let cstr_param = match CString::new(filename) { - Ok(cstr) => cstr, - Err(_) => panic!("CString creation from input filename failed"), - }; - - let err_val = unsafe { af_save_image(cstr_param.as_ptr(), input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Save an Array without modifications to an image file -/// -/// This function only accepts U8, U16, F32 arrays. These arrays are saved to images without any modifications. You must also note that note all image type support 16 or 32 bit images. The best options for 16 bit images are PNG, PPM and TIFF. The best option for 32 bit images is TIFF. These allow lossless storage. -/// -/// The images stored have the following properties: -/// -/// Array Type | Bits per Color (Gray/RGB/RGBA Bits Per Pixel) | Range -/// -------------|-----------------------------------------------|--------------- -/// U8 | 8 ( 8/24/32 BPP) | 0 - 255 -/// U16 | 16 (16/48/64 BPP) | 0 - 65535 -/// F32 | 32 (32/96/128 BPP) | 0 - 1 -/// -/// # Parameters -/// -/// - `filename` is name of file to be saved -/// - `input` is the Array to be saved. Should be U8 for saving 8-bit image, U16 for 16-bit image, and F32 for 32-bit image. -#[allow(clippy::match_wild_err_arm)] -pub fn save_image_native(filename: String, input: &Array) -where - T: HasAfEnum + ImageNativeType, -{ - let cstr_param = match CString::new(filename) { - Ok(cstr) => cstr, - Err(_) => panic!("CString creation from input filename failed"), - }; - - let err_val = unsafe { af_save_image_native(cstr_param.as_ptr(), input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Resize an Image -/// -/// Resizing an input image can be done using either NEAREST or BILINEAR interpolations. -/// Nearest interpolation will pick the nearest value to the location, whereas bilinear -/// interpolation will do a weighted interpolation for calculate the new size. -/// -/// This function does not differentiate between images and data. As long as the array is defined -/// and the output dimensions are not 0, it will resize any type or size of array. -/// -/// # Parameters -/// -/// - `input` is the image to be resized -/// - `odim0` is the output height -/// - `odim1` is the output width -/// - `method` indicates which interpolation method to use for resizing. It uses enum -/// [InterpType](./enum.InterpType.html) to identify the interpolation method. -/// -/// # Return Values -/// -/// Resized Array -pub fn resize( - input: &Array, - odim0: i64, - odim1: i64, - method: InterpType, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_resize( - &mut temp as *mut af_array, - input.get(), - odim0 as dim_t, - odim1 as dim_t, - method as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Transform(Affine) an Image -/// -/// The transform function uses an affine transform matrix to tranform an input image into a new -/// one. The transform matrix tf is a 3x2 matrix of type float. The matrix operation is applied to each -/// location (x, y) that is then transformed to (x', y') of the new array. Hence the transformation -/// is an element-wise operation. -/// -/// The operation is as below: tf = [r00 r10 r01 r11 t0 t1] -/// -/// x' = x * r00 + y * r01 + t0; y' = x * r10 + y * r11 + t1; -/// -/// Interpolation types of NEAREST, LINEAR, BILINEAR and CUBIC are allowed. Affine transforms can be used for various purposes. [translate](./fn.translate.html), [scale](./fn.scale.html) and [skew](./fn.skew.html) are -/// specializations of the transform function. -/// -/// This function can also handle batch operations. -/// -/// # Parameters -/// -/// - `input` is the image to be resized -/// - `trans` is the transformation matrix to be used for image transformation -/// - `odim0` is the output height -/// - `odim1` is the output width -/// - `method` indicates which interpolation method to use for resizing. It uses enum -/// [InterpType](./enum.InterpType.html) to identify the interpolation method. -/// - `is_inverse` indicates if to apply inverse/forward transform -/// -/// # Return Values -/// -/// Transformed Array -pub fn transform( - input: &Array, - trans: &Array, - odim0: i64, - odim1: i64, - method: InterpType, - is_inverse: bool, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_transform( - &mut temp as *mut af_array, - input.get(), - trans.get(), - odim0 as dim_t, - odim1 as dim_t, - method as c_uint, - is_inverse, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Rotate an Image -/// -/// Rotating an input image can be done using either NEAREST or BILINEAR interpolations. -/// Nearest interpolation will pick the nearest value to the location, whereas bilinear -/// interpolation will do a weighted interpolation for calculate the new size. -/// -/// This function does not differentiate between images and data. As long as the array is defined, -/// it will rotate any type or size of array. -/// -/// The crop option allows you to choose whether to resize the image. If crop is set to false, ie. -/// the entire rotated image will be a part of the array and the new array size will be greater -/// than or equal to the input array size. If crop is set to true, then the new array size is same -/// as the input array size and the data that falls outside the boundaries of the array is -/// discarded. -/// -/// Any location of the rotated array that does not map to a location of the input array is set to -/// 0. -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `theta` is the amount of angle (in radians) image should be rotated -/// - `crop` indicates if the rotated image has to be cropped to original size -/// - `method` indicates which interpolation method to use for rotating the image. It uses enum -/// [InterpType](./enum.InterpType.html) to identify the interpolation method. -/// -/// # Return Values -/// -/// Rotated Array -pub fn rotate( - input: &Array, - theta: f64, - crop: bool, - method: InterpType, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_rotate( - &mut temp as *mut af_array, - input.get(), - theta as c_float, - crop, - method as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Translate an Image -/// -/// Translating an image is moving it along 1st and 2nd dimensions by trans0 and trans1. Positive -/// values of these will move the data towards negative x and negative y whereas negative values of -/// these will move the positive right and positive down. See the example below for more. -/// -/// To specify an output dimension, use the odim0 and odim1 for dim0 and dim1 respectively. The -/// size of 2rd and 3rd dimension is same as input. If odim0 and odim1 and not defined, then the -/// output dimensions are same as the input dimensions and the data out of bounds will be -/// discarded. -/// -/// All new values that do not map to a location of the input array are set to 0. -/// -/// Translate is a special case of the [transform](./fn.transform.html) function. -/// -/// # Parameters -/// -/// - `input` is input image -/// - `trans0` is amount by which the first dimension is translated -/// - `trans1` is amount by which the second dimension is translated -/// - `odim0` is the first output dimension -/// - `odim1` is the second output dimension -/// - `method` is the interpolation type (Nearest by default) -/// -/// # Return Values -/// -/// Translated Image(Array). -pub fn translate( - input: &Array, - trans0: f32, - trans1: f32, - odim0: i64, - odim1: i64, - method: InterpType, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_translate( - &mut temp as *mut af_array, - input.get(), - trans0, - trans1, - odim0 as dim_t, - odim1 as dim_t, - method as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Scale an Image -/// -/// Scale is the same functionality as [resize](./fn.resize.html) except that the scale function uses the transform kernels. The other difference is that scale does not set boundary values to be the boundary of the input array. Instead these are set to 0. -/// -/// Scale is a special case of the [transform](./fn.transform.html) function. -/// -/// # Parameters -/// -/// - `input` is input image -/// - `trans0` is amount by which the first dimension is translated -/// - `trans1` is amount by which the second dimension is translated -/// - `odim0` is the first output dimension -/// - `odim1` is the second output dimension -/// - `method` is the interpolation type (Nearest by default) -/// -/// # Return Values -/// -/// Translated Image(Array). -pub fn scale( - input: &Array, - scale0: f32, - scale1: f32, - odim0: i64, - odim1: i64, - method: InterpType, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_scale( - &mut temp as *mut af_array, - input.get(), - scale0, - scale1, - odim0 as dim_t, - odim1 as dim_t, - method as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Skew an image -/// -/// Skew function skews the input array along dim0 by skew0 and along dim1 by skew1. The skew -/// areguments are in radians. Skewing the data means the data remains parallel along 1 dimensions -/// but the other dimensions gets moved along based on the angle. If both skew0 and skew1 are -/// specified, then the data will be skewed along both directions. Explicit output dimensions -/// can be specified using odim0 and odim1. All new values that do not map to a location of the input array are set to 0. -/// -/// Skew is a special case of the [transform](./fn.transform.html) function. -/// -/// # Parameters -/// -/// - `input` is the image to be skewed -/// - `skew0` is the factor by which data is skewed along first dimension -/// - `skew1` is the factor by which data is skewed along second dimension -/// - `odim0` is the output length along first dimension -/// - `odim1` is the output length along second dimension -/// - `method` indicates which interpolation method to use for rotating the image. It uses enum -/// [InterpType](./enum.InterpType.html) to identify the interpolation method. -/// - `is_inverse` indicates if to apply inverse/forward transform -/// -/// # Return Values -/// -/// Skewed Image -pub fn skew( - input: &Array, - skew0: f32, - skew1: f32, - odim0: i64, - odim1: i64, - method: InterpType, - is_inverse: bool, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_skew( - &mut temp as *mut af_array, - input.get(), - skew0, - skew1, - odim0 as dim_t, - odim1 as dim_t, - method as c_uint, - is_inverse, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Compute Histogram of an Array -/// -/// A histogram is a representation of the distribution of given data. This representation is -/// essentially a graph consisting of the data range or domain on one axis and frequency of -/// occurence on the other axis. All the data in the domain is counted in the appropriate bin. The -/// total number of elements belonging to each bin is known as the bin's frequency. -/// -/// The regular histogram function creates bins of equal size between the minimum and maximum of -/// the input data (min and max are calculated internally). The histogram min-max function takes -/// input parameters minimum and maximum, and divides the bins into equal sizes within the range -/// specified by min and max parameters. All values less than min in the data range are placed in -/// the first (min) bin and all values greater than max will be placed in the last (max) bin. -/// -/// # Parameters -/// -/// - `input` is the Array whose histogram has to be computed -/// - `nbins` is the number bins the input data has to be categorized into. -/// - `minval` is the minimum value of bin ordering -/// - `maxval` is the maximum value of bin ordering -/// -/// # Return Values -/// -/// Histogram of input Array -pub fn histogram(input: &Array, nbins: u32, minval: f64, maxval: f64) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_histogram( - &mut temp as *mut af_array, - input.get(), - nbins, - minval, - maxval, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Dilate an Image -/// -/// The dilation function takes two pieces of data as inputs. The first is the input image to be -/// morphed, and the second is the mask indicating the neighborhood around each pixel to match. -/// -/// In dilation, for each pixel, the mask is centered at the pixel. If the center pixel of the mask -/// matches the corresponding pixel on the image, then the mask is accepted. If the center pixels -/// do not matches, then the mask is ignored and no changes are made. -/// -/// For further reference, see [here](https://en.wikipedia.org/wiki/Dilation_(morphology)). -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `mask` is the morphological operation mask -/// -/// # Return Values -/// -/// Dilated Image(Array) -pub fn dilate(input: &Array, mask: &Array) -> Array -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_dilate(&mut temp as *mut af_array, input.get(), mask.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Erode an Image -/// -/// The erosion function is a morphological transformation on an image that requires two inputs. -/// The first is the image to be morphed, and the second is the mask indicating neighborhood that -/// must be white in order to preserve each pixel. -/// -/// In erode, for each pixel, the mask is centered at the pixel. If each pixel of the mask matches -/// the corresponding pixel on the image, then no change is made. If there is at least one -/// mismatch, then pixels are changed to the background color (black). -/// -/// For further reference, see [here](https://en.wikipedia.org/wiki/Erosion_(morphology)). -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `mask` is the morphological operation mask -/// -/// # Return Values -/// -/// Eroded Image(Array) -pub fn erode(input: &Array, mask: &Array) -> Array -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_erode(&mut temp as *mut af_array, input.get(), mask.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Dilate a Volume -/// -/// Dilation for a volume is similar to the way dilation works on an image. Only difference is that -/// the masking operation is performed on a volume instead of a rectangular region. -/// -/// # Parameters -/// -/// - `input` is the input volume -/// - `mask` is the morphological operation mask -/// -/// # Return Values -/// -/// Dilated Volume(Array) -pub fn dilate3(input: &Array, mask: &Array) -> Array -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_dilate3(&mut temp as *mut af_array, input.get(), mask.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Erode a Volume -/// -/// Erosion for a volume is similar to the way erosion works on an image. Only difference is that -/// the masking operation is performed on a volume instead of a rectangular region. -/// -/// # Parameters -/// -/// - `input` is the input volume -/// - `mask` is the morphological operation mask -/// -/// # Return Values -/// -/// Eroded Volume(Array) -pub fn erode3(input: &Array, mask: &Array) -> Array -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_erode3(&mut temp as *mut af_array, input.get(), mask.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Bilateral Filter. -/// -/// A bilateral filter is a edge-preserving filter that reduces noise in an image. The intensity of -/// each pixel is replaced by a weighted average of the intensities of nearby pixels. The weights -/// follow a Gaussian distribution and depend on the distance as well as the color distance. -/// -/// The bilateral filter requires the size of the filter (in pixels) and the upper bound on color -/// values, N, where pixel values range from 0–N inclusively. -/// -/// # Parameters -/// -/// - `input` array is the input image -/// - `spatial_sigma` is the spatial variance parameter that decides the filter window -/// - `chromatic_sigma` is the chromatic variance parameter -/// - `iscolor` indicates if the input is color image or grayscale -/// -/// # Return Values -/// -/// Filtered Image - Array -pub fn bilateral( - input: &Array, - spatial_sigma: f32, - chromatic_sigma: f32, - iscolor: bool, -) -> Array -where - T: HasAfEnum + ImageFilterType, - T::AbsOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_bilateral( - &mut temp as *mut af_array, - input.get(), - spatial_sigma, - chromatic_sigma, - iscolor, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Meanshift Filter. -/// -/// A meanshift filter is an edge-preserving smoothing filter commonly used in object tracking and -/// image segmentation. -/// -/// This filter replaces each pixel in the image with the mean of the values within a given given -/// color and spatial radius. The meanshift filter is an iterative algorithm that continues until a -/// maxium number of iterations is met or until the value of the means no longer changes. -/// -/// # Parameters -/// -/// - `input` array is the input image -/// - `spatial_sigma` is the spatial variance parameter that decides the filter window -/// - `chromatic_sigma` is the chromatic variance parameter -/// - `iter` is the number of iterations filter operation is performed -/// - `iscolor` indicates if the input is color image or grayscale -/// -/// # Return Values -/// -/// Filtered Image - Array -pub fn mean_shift( - input: &Array, - spatial_sigma: f32, - chromatic_sigma: f32, - iter: u32, - iscolor: bool, -) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_mean_shift( - &mut temp as *mut af_array, - input.get(), - spatial_sigma, - chromatic_sigma, - iter, - iscolor, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! filt_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `input` is the input image(Array) - /// - `wlen` is the horizontal length of the filter - /// - `hlen` is the vertical length of the filter - /// - `etype` is enum of type [BorderType](./enum.BorderType.html) - /// - ///# Return Values - /// - /// An Array with filtered image data. - pub fn $fn_name(input: &Array, wlen: u64, wwid: u64, etype: BorderType) -> Array - where - T: HasAfEnum + ImageFilterType, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut temp as *mut af_array, - input.get(), - wlen as dim_t, - wwid as dim_t, - etype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -filt_func_def!("Median filter", medfilt, af_medfilt); -filt_func_def!( - "Box filter with minimum as box operation", - minfilt, - af_minfilt -); -filt_func_def!( - "Box filter with maximum as box operation", - maxfilt, - af_maxfilt -); - -/// Creates a Gaussian Kernel. -/// -/// This function creates a kernel of a specified size that contains a Gaussian distribution. This -/// distribution is normalized to one. This is most commonly used when performing a Gaussian blur -/// on an image. The function takes two sets of arguments, the size of the kernel (width and height -/// in pixels) and the sigma parameters (for row and column) which effect the distribution of the -/// weights in the y and x directions, respectively. -/// -/// Changing sigma causes the weights in each direction to vary. Sigma is calculated internally as -/// (0.25 * rows + 0.75) for rows and similarly for columns. -/// -/// # Parameters -/// -/// - `rows` is number of rows of kernel -/// - `cols` is number of cols of kernel -/// - `sigma_r` is standard deviation of rows -/// - `sigma_c` is standard deviation of cols -/// -/// # Return Values -/// -/// An Array with gaussian kernel values -pub fn gaussian_kernel(rows: i32, cols: i32, sigma_r: f64, sigma_c: f64) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_gaussian_kernel(&mut temp as *mut af_array, rows, cols, sigma_r, sigma_c) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Color space conversion -/// -/// Following are the supported conversions -/// -/// - RGB => GRAY -/// - GRAY => RGB -/// - RGB => HSV -/// - HSV => RGB -/// - YCbCr => RGB -/// - RGB => YCbCr -/// -/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores -/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of -/// these three values produces the gamut of unique colors. -/// -/// HSV (Hue, Saturation, Value), also known as HSB (hue, saturation, brightness), is often used by -/// artists because it is more natural to think about a color in terms of hue and saturation than -/// in terms of additive or subtractive color components (as in RGB). HSV is a transformation of -/// RGB colorspace; its components and colorimetry are relative to the RGB colorspace from which it -/// was derived. Like RGB, HSV also uses 3 values per pixel. -/// -/// GRAY is a single channel color space where pixel value ranges from 0 to 1. Zero represents -/// black, one represent white and any value between zero & one is a gray value -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `tospace` is the target color space. Takes values of [ColorSpace](./enum.ColorSpace.html) -/// - `fromspace` is the source image color space. Takes values of -/// [ColorSpace](./enum.ColorSpace.html) -/// -/// # Return Values -/// -/// An Array with input image values in target color space -pub fn color_space(input: &Array, tospace: ColorSpace, fromspace: ColorSpace) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_color_space( - &mut temp as *mut af_array, - input.get(), - tospace as c_uint, - fromspace as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find blobs in given image. -/// -/// Given a binary image (with zero representing background pixels), regions computes a floating -/// point image where each connected component is labeled from 1 to N, the total number of -/// components in the image. -/// -/// A component is defined as one or more nonzero pixels that are connected by the specified -/// connectivity (either [`Connectivity::FOUR`](./enum.Connectivity.html) or [`Connectivity::EIGHT`](./enum.Connectivity.html)) in two dimensions. -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `conn` can take one of the values of [Connectivity](./enum.Connectivity.html) -/// -/// # Return Values -/// -/// Array with labels indicating different regions -pub fn regions(input: &Array, conn: Connectivity) -> Array -where - OutType: HasAfEnum + RealNumber, -{ - let otype = OutType::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_regions( - &mut temp as *mut af_array, - input.get(), - conn as c_uint, - otype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Sobel Operator -/// -/// Sobel operators perform a 2-D spatial gradient measurement on an image to emphasize the regions -/// of high spatial frequency, namely edges. A more in depth discussion on it can be found [here](https://en.wikipedia.org/wiki/Sobel_operator). -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `ker_size` is the kernel size of sobel operator -/// -/// # Return Values -/// -/// A tuple of Arrays. -/// -/// The first Array has derivatives along horizontal direction -/// -/// The second Array has derivatives along vertical direction -pub fn sobel(input: &Array, ker_size: u32) -> (Array, Array) -where - T: HasAfEnum + ImageFilterType, - T::SobelOutType: HasAfEnum, -{ - let mut dx: af_array = std::ptr::null_mut(); - let mut dy: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_sobel_operator( - &mut dx as *mut af_array, - &mut dy as *mut af_array, - input.get(), - ker_size, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (dx.into(), dy.into()) -} - -/// Histogram Equalization -/// -/// # Parameters -/// -/// - `input` is the input Array to be equalized -/// - `hist` is the Array to be used for equalizing input -/// -/// # Return Values -/// Equalized Array -pub fn hist_equal(input: &Array, hist: &Array) -> Array -where - T: HasAfEnum + RealNumber, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_hist_equal(&mut temp as *mut af_array, input.get(), hist.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! grayrgb_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `r` is fraction of red channel to appear in output - /// - `g` is fraction of green channel to appear in output - /// - `b` is fraction of blue channel to appear in output - /// - ///#Return Values - /// - ///An Array with image data in target color space - pub fn $fn_name(input: &Array, r: f32, g: f32, b: f32) -> Array - where - T: HasAfEnum + GrayRGBConvertible, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_name(&mut temp as *mut af_array, input.get(), r, g, b) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -grayrgb_func_def!("Color(RGB) to Grayscale conversion", rgb2gray, af_rgb2gray); -grayrgb_func_def!("Grayscale to Color(RGB) conversion", gray2rgb, af_gray2rgb); - -macro_rules! hsvrgb_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => { - #[doc=$doc_str] - pub fn $fn_name(input: &Array) -> Array - where - T: HasAfEnum + RealFloating, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_name(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -hsvrgb_func_def!("HSV to RGB color space conversion", hsv2rgb, af_hsv2rgb); -hsvrgb_func_def!("RGB to HSV color space conversion", rgb2hsv, af_rgb2hsv); - -/// Generate an array with image windows as columns -/// -/// unwrap takes in an input image along with the window sizes wx and wy, strides sx and sy, and -/// padding px and py. This function then generates a matrix where each windows is an independent -/// column. -/// -/// The number of columns (rows if is_column is true) in the output array are govenered by the -/// number of windows that can be fit along x and y directions. Padding is applied along all 4 -/// sides of the matrix with px defining the height of the padding along dim 0 and py defining the -/// width of the padding along dim 1. -/// -/// The first column window is always at the top left corner of the input including padding. If a -/// window cannot fit before the end of the matrix + padding, it is skipped from the generated -/// matrix. -/// -/// Padding can take a maximum value of window - 1 repectively for x and y. -/// -/// For multiple channels (3rd and 4th dimension), the generated matrix contains the same number of -/// channels as the input matrix. Each channel of the output matrix corresponds to the same channel -/// of the input. -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `wx` is the block window size along 0th-dimension between \[1, input.dims\[0\] + px\] -/// - `wy` is the block window size along 1st-dimension between \[1, input.dims\[1\] + py\] -/// - `sx` is the stride along 0th-dimension -/// - `sy` is the stride along 1st-dimension -/// - `px` is the padding along 0th-dimension between [0, wx). Padding is applied both before and after. -/// - `py` is the padding along 1st-dimension between [0, wy). Padding is applied both before and after. -/// - `is_column` specifies the layout for the unwrapped patch. If is_column is false, the unrapped patch is laid out as a row. -/// -/// # Return Values -/// -/// An Array with image windows as columns -/// -/// # Examples -/// -/// ```text -/// A [5 5 1 1] -/// 10 15 20 25 30 -/// 11 16 21 26 31 -/// 12 17 22 27 32 -/// 13 18 23 28 33 -/// 14 19 24 29 34 -/// -/// // Window 3x3, strides 1x1, padding 0x0 -/// unwrap(A, 3, 3, 1, 1, 0, 0, False) [9 9 1 1] -/// 10 11 12 15 16 17 20 21 22 -/// 11 12 13 16 17 18 21 22 23 -/// 12 13 14 17 18 19 22 23 24 -/// 15 16 17 20 21 22 25 26 27 -/// 16 17 18 21 22 23 26 27 28 -/// 17 18 19 22 23 24 27 28 29 -/// 20 21 22 25 26 27 30 31 32 -/// 21 22 23 26 27 28 31 32 33 -/// 22 23 24 27 28 29 32 33 34 -/// -/// // Window 3x3, strides 1x1, padding 1x1 -/// unwrap(A, 3, 3, 1, 1, 1, 1, False) [9 25 1 1] -/// 0 0 0 0 0 0 10 11 12 13 0 15 16 17 18 0 20 21 22 23 0 25 26 27 28 -/// 0 0 0 0 0 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 -/// 0 0 0 0 0 11 12 13 14 0 16 17 18 19 0 21 22 23 24 0 26 27 28 29 0 -/// 0 10 11 12 13 0 15 16 17 18 0 20 21 22 23 0 25 26 27 28 0 30 31 32 33 -/// 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 -/// 11 12 13 14 0 16 17 18 19 0 21 22 23 24 0 26 27 28 29 0 31 32 33 34 0 -/// 0 15 16 17 18 0 20 21 22 23 0 25 26 27 28 0 30 31 32 33 0 0 0 0 0 -/// 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 0 0 0 0 0 -/// 16 17 18 19 0 21 22 23 24 0 26 27 28 29 0 31 32 33 34 0 0 0 0 0 0 -/// ``` -#[allow(clippy::too_many_arguments)] -pub fn unwrap( - input: &Array, - wx: i64, - wy: i64, - sx: i64, - sy: i64, - px: i64, - py: i64, - is_column: bool, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_unwrap( - &mut temp as *mut af_array, - input.get(), - wx, - wy, - sx, - sy, - px, - py, - is_column, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Converts unwrapped image to an image -/// -/// Wrap takes an unwrapped image (see unwrap()) and converts it back to an image. -/// -/// The inputs to this function should be the same as the inputs used to generate the unwrapped -/// image. -/// -/// # Parameters -/// -/// - `input` is the output of unwrap function call -/// - `ox` is the 0th-dimension of output image -/// - `oy` is the 1st-dimension of output image -/// - `wx` is the block window size along 0th-dimension between -/// - `wy` is the block window size along 1st-dimension between -/// - `sx` is the stride along 0th-dimension -/// - `sy` is the stride along 1st-dimension -/// - `px` is the padding used along 0th-dimension between [0, wx). -/// - `py` is the padding used along 1st-dimension between [0, wy). -/// - `is_column` specifies the layout for the unwrapped patch. If is_column is false, the rows are treated as the patches -/// -/// # Return Values -/// -/// Image(Array) created from unwrapped Image(Array) -#[allow(clippy::too_many_arguments)] -pub fn wrap( - input: &Array, - ox: i64, - oy: i64, - wx: i64, - wy: i64, - sx: i64, - sy: i64, - px: i64, - py: i64, - is_column: bool, -) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_wrap( - &mut temp as *mut af_array, - input.get(), - ox, - oy, - wx, - wy, - sx, - sy, - px, - py, - is_column, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Summed area table of an Image -/// -/// # Parameters -/// -/// - `input` is the input image -/// -/// # Return Values -/// -/// Summed area table (a.k.a Integral Image) of the input image. -pub fn sat(input: &Array) -> Array -where - T: HasAfEnum + RealNumber, - T::AggregateOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sat(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// RGB to YCbCr colorspace converter. -/// -/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores -/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of -/// these three values produces the gamut of unique colors. -/// -/// YCbCr is a family of color spaces used as a part of the color image pipeline in video and -/// digital photography systems where Y is luma component and Cb & Cr are the blue-difference and -/// red-difference chroma components. -/// -/// Input array to this function should be of real data in the range \[0,1\]. -/// -/// # Parameters -/// -/// - `input` is the input image in RGB color space -/// - `standard` is the target color space - [YCbCr standard](./enum.YCCStd.html) -/// -/// # Return Values -/// -/// Image(Array) in YCbCr color space -pub fn rgb2ycbcr(input: &Array, standard: YCCStd) -> Array -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_rgb2ycbcr(&mut temp as *mut af_array, input.get(), standard as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// YCbCr to RGB colorspace converter. -/// -/// YCbCr is a family of color spaces used as a part of the color image pipeline in video and -/// digital photography systems where Y is luma component and Cb & Cr are the blue-difference and -/// red-difference chroma components. -/// -/// RGB (Red, Green, Blue) is the most common format used in computer imaging. RGB stores -/// individual values for red, green and blue, and hence the 3 values per pixel. A combination of -/// these three values produces the gamut of unique colors. -/// -/// Input array to this function should be of real data with the following range in their -/// respective channels. -/// -/// - Y −> \[16,219\] -/// - Cb −> \[16,240\] -/// - Cr −> \[16,240\] -/// -/// # Parameters -/// -/// - `input` is the input image in YCbCr color space -/// - `standard` is the [YCbCr standard](./enum.YCCStd.html) in which input image color space is -/// present. -/// -/// # Return Values -/// -/// Image(Array) in RGB color space -pub fn ycbcr2rgb(input: &Array, standard: YCCStd) -> Array -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_ycbcr2rgb(&mut temp as *mut af_array, input.get(), standard as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Function to check if Image I/O is available -/// -/// # Parameters -/// -/// None -/// -/// # Return Values -/// -/// Return a boolean indicating if ArrayFire was compiled with Image I/O support -pub fn is_imageio_available() -> bool { - let mut temp: bool = false; - unsafe { - af_is_image_io_available(&mut temp as *mut bool); - } - temp -} - -/// Transform input coordinates -/// -/// The transform function uses a perspective transform matrix to transform input coordinates -/// (given as two dimensions) into a coordinates matrix. -/// -/// The output is a 4x2 matrix, indicating the coordinates of the 4 bidimensional transformed -/// points. -/// -/// # Parameters -/// -/// - `tf` is the transformation matrix -/// - `d0` is the first input dimension -/// - `d1` is the second input dimension -/// -/// # Return Values -/// -/// Transformed coordinates -pub fn transform_coords(tf: &Array, d0: f32, d1: f32) -> Array -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_transform_coordinates(&mut temp as *mut af_array, tf.get(), d0, d1) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find Image moments -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `moment` is the type of moment to be computed, takes a value of -/// [enum](./enum.MomentType.html) -/// -/// # Return Values -/// -/// Moments Array -pub fn moments(input: &Array, moment: MomentType) -> Array -where - T: HasAfEnum + MomentsComputable, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_moments(&mut temp as *mut af_array, input.get(), moment as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find Image moment for whole image -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `moment` is the type of moment to be computed, takes a value of -/// [enum](./enum.MomentType.html) -/// -/// # Return Values -/// -/// Moment value of the whole image -pub fn moments_all(input: &Array, moment: MomentType) -> f64 -where - T: HasAfEnum + MomentsComputable, -{ - let mut temp: f64 = 0.0; - - let err_val = - unsafe { af_moments_all(&mut temp as *mut c_double, input.get(), moment as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - - temp -} - -/// One dimensional median filter on image -/// -/// # Parameters -/// -/// - `input` is the input image(Array) -/// - `wlen` is the horizontal length of the filter -/// - `etype` is enum of type [BorderType](./enum.BorderType.html) -/// -/// # Return Values -/// -/// An Array with filtered image data. -pub fn medfilt1(input: &Array, wlen: u64, etype: BorderType) -> Array -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_medfilt1( - &mut temp as *mut af_array, - input.get(), - wlen as dim_t, - etype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Canny edge detection operator -/// -/// The Canny edge detector is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images. A more in depth discussion on it can be found [here](https://en.wikipedia.org/wiki/Canny_edge_detector). -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `threshold_type` helps determine if user set high threshold is to be used or not. It can take values defined by the enum [CannyThresholdType](./enum.CannyThresholdType.html) -/// - `low` is the lower threshold % of the maximum or auto-derived high -/// - `high` is the higher threshold % of maximum value in gradient image used in hysteresis procedure. This value is ignored if [CannyThresholdType::OTSU](./enum.CannyThresholdType.html) is chosen. -/// - `sobel_window` is the window size of sobel kernel for computing gradient direction and magnitude. -/// - `is_fast` indicates if L1 norm(faster but less accurate) is used to compute image gradient magnitude instead of L2 norm. -/// -/// # Return Values -/// -/// An Array of binary type [DType::B8](./enum.DType.html) indicating edges(All pixels with -/// non-zero values are edges). -pub fn canny( - input: &Array, - threshold_type: CannyThresholdType, - low: f32, - high: f32, - sobel_window: u32, - is_fast: bool, -) -> Array -where - T: HasAfEnum + EdgeComputable, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_canny( - &mut temp as *mut af_array, - input.get(), - threshold_type as c_int, - low, - high, - sobel_window as c_uint, - is_fast, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Anisotropic smoothing filter -/// -/// Anisotropic diffusion algorithm aims at removing noise in the images -/// while preserving important features such as edges. The algorithm -/// essentially creates a scale space representation of the original -/// image, where image from previous step is used to create a new version -/// of blurred image using the diffusion process. Standard isotropic diffusion -/// methods such as gaussian blur, doesn't take into account the local -/// content(smaller neighborhood of current processing pixel) while removing -/// noise. Anisotropic diffusion uses the flux equations given below to -/// achieve that. Flux equation is the formula used by the diffusion process -/// to determine how much a pixel in neighborhood should contribute to -/// the blurring operation being done at the current pixel at a given iteration. -/// -/// The flux function can be either exponential or quadratic. -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -///
Available Flux Functions
-/// AF_FLUX_QUADRATIC -/// -/// \begin{equation} -/// \frac{1}{1 + (\frac{\| \nabla I\|}{K})^2} -/// \end{equation} -///
-/// AF_FLUX_EXPONENTIAL -/// -/// \begin{equation} -/// \exp{-(\frac{\| \nabla I\|}{K})^2} -/// \end{equation} -///
-/// -/// Please be cautious using the time step parameter to the function. -/// Appropriate time steps for solving this type of p.d.e. depend on -/// the dimensionality of the image and the order of the equation. -/// Stable values for most 2D and 3D functions are 0.125 and 0.0625, -/// respectively. The time step values are automatically constrained -/// to the stable value. -/// -/// Another input parameter to be cautious about is the conductance -/// parameter, lower values strongly preserve image features and -/// vice-versa. For human vision, this value ranges from 0.5 to 2.0. -/// -/// # Parameters -/// -/// - `img` is the noisy input image -/// - `dt` is the timestep for diffusion equation -/// - `k` is the conductance parameter for diffusion -/// - `iters` is the number of iterations diffusion is performed -/// - `fftype` dictates the type of flux flow and it is an -/// [enum](./enum.DiffusionEq.html) -/// - `diff_kind` dictates the type of diffusion and it is an -/// [enum](./enum.FluxFn.html) -/// -/// # Return Values -/// -/// Returns an anisotropically smoothed and noise-free image -/// -/// ### References -/// -/// - Pietro Perona and Jitendra Malik, `Scale-space and edge detection -/// using anisotropic diffusion,` IEEE Transactions on Pattern Analysis -/// Machine Intelligence, vol. 12, pp. 629-639, 1990. -/// - R. Whitaker and X. Xue. `Variable-Conductance, Level-Set Curvature -/// for Image Denoising`, International Conference on Image Processing, -/// 2001 pp. 142-145, Vol.3. -pub fn anisotropic_diffusion( - img: &Array, - dt: f32, - k: f32, - iters: u32, - fftype: FluxFn, - diff_kind: DiffusionEq, -) -> Array -where - T: HasAfEnum + EdgeComputable, - T::AbsOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_anisotropic_diffusion( - &mut temp as *mut af_array, - img.get(), - dt, - k, - iters, - fftype as c_uint, - diff_kind as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Segment image based on similar pixel characteristics -/// -/// This filter is similar to [regions](./fn.regions.html) with additional criteria for -/// segmentation. In regions, all connected pixels are considered to be a single component. -/// In this variation of connected components, pixels having similar pixel statistics of the -/// neighborhoods around a given set of seed points are grouped together. -/// -/// The parameter `radius` determines the size of neighborhood around a seed point. -/// -/// Mean and Variance are the pixel statistics that are computed across all neighborhoods around -/// the given set of seed points. The pixels which are connected to seed points and lie in the -/// confidence interval are grouped together. Given below is the confidence interval. -/// -/// \begin{equation} -/// [\mu - \alpha * \sigma, \mu + \alpha * \sigma] -/// \end{equation} -/// where -/// -/// - $ \mu $ is the mean of the pixels in the seed neighborhood -/// - $ \sigma^2 $ is the variance of the pixels in the seed neighborhood -/// - $ \alpha $ is the multiplier used to control the width of the confidence interval. -/// -/// This filter follows an iterative approach for fine tuning the segmentation. An initial -/// segmenetation followed by a finite number `iterations` of segmentations are performed. -/// The user provided parameter `iterations` is only a request and the algorithm can prempt -/// the execution if variance approaches zero. The initial segmentation uses the mean and -/// variance calculated from the neighborhoods of all the seed points. For subsequent -/// segmentations, all pixels in the previous segmentation are used to re-calculate the mean -/// and variance (as opposed to using the pixels in the neighborhood of the seed point). -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `seedx` contains the x coordinates of seeds in image coordinates -/// - `seedy` contains the y coordinates of seeds in image coordinates -/// - `radius` is the neighborhood region to be considered around each seed point -/// - `multiplier` controls the threshold range computed from the mean and variance of seed point neighborhoods -/// - `iterations` is the number of times the segmentation in performed -/// - `segmented_value` is the value to which output array valid pixels are set to -/// -/// # Return Values -/// -/// Segmented(based on pixel characteristics) image(Array) with regions surrounding the seed points -pub fn confidence_cc( - input: &Array, - seedx: &Array, - seedy: &Array, - radius: u32, - multiplier: u32, - iterations: u32, - segmented_val: f64, -) -> Array -where - InOutType: ConfidenceCCInput, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_confidence_cc( - &mut temp as *mut af_array, - input.get(), - seedx.get(), - seedy.get(), - radius, - multiplier, - iterations as i32, - segmented_val, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Iterative Deconvolution -/// -/// The following table shows the iteration update equations of the respective -/// deconvolution algorithms. -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -/// -///
AlgorithmUpdate Equation
LandWeber -/// $ \hat{I}_{n} = \hat{I}_{n-1} + \alpha * P^T \otimes (I - P \otimes \hat{I}_{n-1}) $ -///
Richardson-Lucy -/// $ \hat{I}_{n} = \hat{I}_{n-1} . ( \frac{I}{\hat{I}_{n-1} \otimes P} \otimes P^T ) $ -///
-/// -/// where -/// -/// - $ I $ is the observed(input/blurred) image -/// - $ P $ is the point spread function -/// - $ P^T $ is the transpose of point spread function -/// - $ \hat{I}_{n} $ is the current iteration's updated image estimate -/// - $ \hat{I}_{n-1} $ is the previous iteration's image estimate -/// - $ \alpha $ is the relaxation factor -/// - $ \otimes $ indicates the convolution operator -/// -/// The type of output Array from deconvolution will be of type f64 if -/// the input array type is f64. For other types, output type will be f32 type. -/// Should the caller want to save the image to disk or require the values of output -/// to be in a fixed range, that should be done by the caller explicitly. -pub fn iterative_deconv( - input: &Array, - kernel: &Array, - iterations: u32, - relaxation_factor: f32, - algo: IterativeDeconvAlgo, -) -> Array -where - T: DeconvInput, - T::AbsOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_iterative_deconv( - &mut temp as *mut af_array, - input.get(), - kernel.get(), - iterations, - relaxation_factor, - algo as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inverse deconvolution -/// -/// This is a linear algorithm i.e. they are non-iterative in -/// nature and usually faster than iterative deconvolution algorithms. -/// -/// Depending on the values passed on to `algo` of type enum [InverseDeconvAlgo](./enum.inverse_deconv_algo.html), -/// different equations are used to compute the final result. -/// -/// #### Tikhonov's Deconvolution Method: -/// -/// The update equation for this algorithm is as follows: -/// -///
-/// \begin{equation} -/// \hat{I}_{\omega} = \frac{ I_{\omega} * P^{*}_{\omega} } { |P_{\omega}|^2 + \gamma } -/// \end{equation} -///
-/// -/// where -/// -/// - $ I_{\omega} $ is the observed(input/blurred) image in frequency domain -/// - $ P_{\omega} $ is the point spread function in frequency domain -/// - $ \gamma $ is a user defined regularization constant -/// -/// The type of output Array from deconvolution will be double if the input array type is double. -/// Otherwise, it will be float in rest of the cases. Should the caller want to save the image to -/// disk or require the values of output to be in a fixed range, that should be done by the caller -/// explicitly. -pub fn inverse_deconv( - input: &Array, - kernel: &Array, - gamma: f32, - algo: InverseDeconvAlgo, -) -> Array -where - T: DeconvInput, - T::AbsOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_inverse_deconv( - &mut temp as *mut af_array, - input.get(), - kernel.get(), - gamma, - algo as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} diff --git a/src/lapack/mod.rs b/src/lapack/mod.rs deleted file mode 100644 index 1866108fe..000000000 --- a/src/lapack/mod.rs +++ /dev/null @@ -1,519 +0,0 @@ -use super::core::{ - af_array, AfError, Array, FloatingPoint, HasAfEnum, MatProp, NormType, HANDLE_ERROR, -}; - -use libc::{c_double, c_int, c_uint}; - -extern "C" { - fn af_svd(u: *mut af_array, s: *mut af_array, vt: *mut af_array, input: af_array) -> c_int; - fn af_svd_inplace( - u: *mut af_array, - s: *mut af_array, - vt: *mut af_array, - input: af_array, - ) -> c_int; - fn af_lu( - lower: *mut af_array, - upper: *mut af_array, - pivot: *mut af_array, - input: af_array, - ) -> c_int; - fn af_lu_inplace(pivot: *mut af_array, input: af_array, is_lapack_piv: bool) -> c_int; - fn af_qr(q: *mut af_array, r: *mut af_array, tau: *mut af_array, input: af_array) -> c_int; - fn af_qr_inplace(tau: *mut af_array, input: af_array) -> c_int; - fn af_cholesky(out: *mut af_array, info: *mut c_int, input: af_array, is_upper: bool) -> c_int; - fn af_cholesky_inplace(info: *mut c_int, input: af_array, is_upper: bool) -> c_int; - fn af_solve(x: *mut af_array, a: af_array, b: af_array, options: c_uint) -> c_int; - fn af_solve_lu( - x: *mut af_array, - a: af_array, - piv: af_array, - b: af_array, - options: c_uint, - ) -> c_int; - fn af_inverse(out: *mut af_array, input: af_array, options: c_uint) -> c_int; - fn af_rank(rank: *mut c_uint, input: af_array, tol: c_double) -> c_int; - fn af_det(det_real: *mut c_double, det_imag: *mut c_double, input: af_array) -> c_int; - fn af_norm( - out: *mut c_double, - input: af_array, - ntype: c_uint, - p: c_double, - q: c_double, - ) -> c_int; - fn af_is_lapack_available(out: *mut bool) -> c_int; - fn af_pinverse(out: *mut af_array, input: af_array, tol: c_double, options: c_uint) -> c_int; -} - -/// Perform Singular Value Decomposition -/// -/// This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S -/// such that -/// -/// A = U∗S∗Vt -/// -/// If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M -/// x N -/// -/// # Parameters -/// -/// - `in` is the input matrix -/// -/// # Return Values -/// -/// A triplet of Arrays. -/// -/// The first Array is the output array containing U -/// -/// The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix)) -/// -/// The third Array is the output array containing V ^ H -pub fn svd(input: &Array) -> (Array, Array, Array) -where - T: HasAfEnum + FloatingPoint, - T::BaseType: HasAfEnum, -{ - let mut u: af_array = std::ptr::null_mut(); - let mut s: af_array = std::ptr::null_mut(); - let mut vt: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_svd( - &mut u as *mut af_array, - &mut s as *mut af_array, - &mut vt as *mut af_array, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (u.into(), s.into(), vt.into()) -} - -/// Perform Singular Value Decomposition inplace -/// -/// This function factorizes a matrix A into two unitary matrices U and Vt, and a diagonal matrix S -/// such that -/// -/// A = U∗S∗Vt -/// -/// If A has M rows and N columns, U is of the size M x M , V is of size N x N, and S is of size M -/// x N -/// -/// # Parameters -/// -/// - `in` is the input/output matrix. This will contain random data after the function call is -/// complete. -/// -/// # Return Values -/// -/// A triplet of Arrays. -/// -/// The first Array is the output array containing U -/// -/// The second Array is the output array containing the diagonal values of sigma, (singular values of the input matrix)) -/// -/// The third Array is the output array containing V ^ H -pub fn svd_inplace(input: &mut Array) -> (Array, Array, Array) -where - T: HasAfEnum + FloatingPoint, - T::BaseType: HasAfEnum, -{ - let mut u: af_array = std::ptr::null_mut(); - let mut s: af_array = std::ptr::null_mut(); - let mut vt: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_svd_inplace( - &mut u as *mut af_array, - &mut s as *mut af_array, - &mut vt as *mut af_array, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (u.into(), s.into(), vt.into()) -} - -/// Perform LU decomposition -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// -/// # Return Values -/// -/// A triplet of Arrays. -/// -/// The first Array will contain the lower triangular matrix of the LU decomposition. -/// -/// The second Array will contain the lower triangular matrix of the LU decomposition. -/// -/// The third Array will contain the permutation indices to map the input to the decomposition. -pub fn lu(input: &Array) -> (Array, Array, Array) -where - T: HasAfEnum + FloatingPoint, -{ - let mut lower: af_array = std::ptr::null_mut(); - let mut upper: af_array = std::ptr::null_mut(); - let mut pivot: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_lu( - &mut lower as *mut af_array, - &mut upper as *mut af_array, - &mut pivot as *mut af_array, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (lower.into(), upper.into(), pivot.into()) -} - -/// Perform inplace LU decomposition -/// -/// # Parameters -/// -/// - `input` contains the input matrix on entry and packed LU decomposition on exit -/// - `is_lapack_pic` specified if the pivot is returned in original LAPACK compliant format -/// -/// # Return Values -/// -/// An Array with permutation indices to map the input to the decomposition. Since, the input -/// matrix is modified in place, only pivot values are returned. -pub fn lu_inplace(input: &mut Array, is_lapack_piv: bool) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut pivot: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_lu_inplace(&mut pivot as *mut af_array, input.get(), is_lapack_piv) }; - HANDLE_ERROR(AfError::from(err_val)); - pivot.into() -} - -/// Perform QR decomposition -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// -/// # Return Values -/// -/// A triplet of Arrays. -/// -/// The first Array is the orthogonal matrix from QR decomposition -/// -/// The second Array is the upper triangular matrix from QR decomposition -/// -/// The third Array will contain additional information needed for solving a least squares problem -/// using q and r -pub fn qr(input: &Array) -> (Array, Array, Array) -where - T: HasAfEnum + FloatingPoint, -{ - let mut q: af_array = std::ptr::null_mut(); - let mut r: af_array = std::ptr::null_mut(); - let mut tau: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_qr( - &mut q as *mut af_array, - &mut r as *mut af_array, - &mut tau as *mut af_array, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (q.into(), r.into(), tau.into()) -} - -/// Perform inplace QR decomposition -/// -/// # Parameters -/// -/// - `input` contains the input matrix on entry, and packed QR decomposition on exit -/// -/// # Return Values -/// -/// An Array with additional information needed for unpacking the data. -pub fn qr_inplace(input: &mut Array) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut tau: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_qr_inplace(&mut tau as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - tau.into() -} - -/// Perform Cholesky decomposition -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// - `is_upper` is a boolean to indicate if the output has to be upper or lower triangular matrix -/// -/// # Return Values -/// -/// A tuple of an Array and signed 32-bit integer. -/// -/// The Array contains the triangular matrix (multiply it with conjugate transpose to reproduce the input). -/// -/// If the integer is 0, it means the cholesky decomposition passed. Otherwise, it will contain the rank at -/// which the decomposition failed. -pub fn cholesky(input: &Array, is_upper: bool) -> (Array, i32) -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let mut info: i32 = 0; - let err_val = unsafe { - af_cholesky( - &mut temp as *mut af_array, - &mut info as *mut c_int, - input.get(), - is_upper, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (temp.into(), info) -} - -/// Perform inplace Cholesky decomposition -/// -/// # Parameters -/// -/// - `input` contains the input matrix on entry, and triangular matrix on exit. -/// - `is_upper` is a boolean to indicate if the output has to be upper or lower triangular matrix -/// -/// # Return Values -/// -/// A signed 32-bit integer. If the integer is 0, it means the cholesky decomposition passed. Otherwise, -/// it will contain the rank at which the decomposition failed. -pub fn cholesky_inplace(input: &mut Array, is_upper: bool) -> i32 -where - T: HasAfEnum + FloatingPoint, -{ - let mut info: i32 = 0; - - let err_val = unsafe { af_cholesky_inplace(&mut info as *mut c_int, input.get(), is_upper) }; - HANDLE_ERROR(AfError::from(err_val)); - - info -} - -/// Solve a system of equations -/// -/// # Parameters -/// -/// - `a` is the coefficient matrix -/// - `b` has the measured values -/// - `options` determine the various properties of matrix a -/// -/// The `options` parameter currently needs to be either `NONE`, `LOWER` or `UPPER`, other values are not supported yet. -/// -/// # Return Values -/// -/// An Array which is the matrix of unknown variables -pub fn solve(a: &Array, b: &Array, options: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_solve( - &mut temp as *mut af_array, - a.get(), - b.get(), - options as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Solve a system of equations -/// -/// # Parameters -/// -/// - `a` is the output matrix from packed LU decomposition of the coefficient matrix -/// - `piv` is the pivot array from packed LU decomposition of the coefficient matrix -/// - `b` has the measured values -/// - `options` determine the various properties of matrix a -/// -/// The `options` parameter currently needs to be `NONE`, other values are not supported yet. -/// -/// # Return Values -/// -/// An Array which is the matrix of unknown variables -pub fn solve_lu(a: &Array, piv: &Array, b: &Array, options: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_solve_lu( - &mut temp as *mut af_array, - a.get(), - piv.get(), - b.get(), - options as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Compute inverse of a matrix -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// - `options` determine various properties of input matrix -/// -/// The parameter `options` currently take only the value `NONE`. -/// -/// # Return Values -/// -/// An Array with values of the inverse of input matrix. -pub fn inverse(input: &Array, options: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_inverse(&mut temp as *mut af_array, input.get(), options as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Find rank of a matrix -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// - `tol` is the tolerance value -/// -/// # Return Values -/// -/// An unsigned 32-bit integer which is the rank of the input matrix. -pub fn rank(input: &Array, tol: f64) -> u32 -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: u32 = 0; - - let err_val = unsafe { af_rank(&mut temp as *mut c_uint, input.get(), tol) }; - HANDLE_ERROR(AfError::from(err_val)); - - temp -} - -/// Find the determinant of the matrix -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// -/// # Return Values -/// -/// A tuple of 32-bit floating point values. -/// -/// If the input matrix is non-complex type, only first values of tuple contains the result. -pub fn det(input: &Array) -> (f64, f64) -where - T: HasAfEnum + FloatingPoint, -{ - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_det( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) -} - -/// Find the norm of a matrix -/// -/// # Parameters -/// -/// - `input` is the input matrix -/// - `ntype` is specifies the required norm type using enum [NormType](./enum.NormType.html) -/// - `p` specifies the value of *P* when `ntype` is one of VECTOR_P, MATRIX_L_PQ. It is ignored -/// for other values of `ntype` -/// - `q` specifies the value of *Q* when `ntype` is MATRIX_L_PQ. This parameter is ignored if -/// `ntype` is anything else. -/// -/// # Return Values -/// -/// A 64-bit floating point value that contains the norm of input matrix. -pub fn norm(input: &Array, ntype: NormType, p: f64, q: f64) -> f64 -where - T: HasAfEnum + FloatingPoint, -{ - let mut out: f64 = 0.0; - - let err_val = unsafe { - af_norm( - &mut out as *mut c_double, - input.get(), - ntype as c_uint, - p, - q, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - out -} - -/// Function to check if lapack support is available -/// -/// # Parameters -/// -/// None -/// -/// # Return Values -/// -/// Return a boolean indicating if ArrayFire was compiled with lapack support -pub fn is_lapack_available() -> bool { - let mut temp: bool = false; - unsafe { - af_is_lapack_available(&mut temp as *mut bool); - } - temp -} - -/// Psuedo Inverse of Matrix -/// -/// # Parameters -/// -/// - `input` is input matrix -/// - `tolerance` defines the lower threshold for singular values from SVD -/// - `option` must be [MatProp::NONE](./enum.MatProp.html) (more options might be supported in the future) -/// -/// Notes: -/// -/// - Tolerance is not the actual lower threshold, but it is passed in as a -/// parameter to the calculation of the actual threshold relative to the shape and contents of input. -/// - First, try setting tolerance to 1e-6 for single precision and 1e-12 for double. -/// -/// # Return -/// -/// Pseudo Inverse matrix for the input matrix -pub fn pinverse(input: &Array, tolerance: f64, option: MatProp) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut out: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_pinverse( - &mut out as *mut af_array, - input.get(), - tolerance, - option as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - out.into() -} diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100755 index 509fefa2a..000000000 --- a/src/lib.rs +++ /dev/null @@ -1,95 +0,0 @@ -//! ArrayFire is a high performance software library for parallel computing with an easy-to-use API. -//! ArrayFire abstracts away much of the details of programming parallel architectures by providing -//! a high-level container object, the [Array](./struct.Array.html), that represents data stored on -//! a CPU, GPU, FPGA, or other type of accelerator. This abstraction permits developers to write -//! massively parallel applications in a high-level language where they need not be concerned about -//! low-level optimizations that are frequently required to achieve high throughput on most parallel -//! architectures. - -//! This crate provides Rust bindings for the ArrayFire library. Given below table shows the rust -//! bindings compatability with ArrayFire upstream. If you find any bugs, please report them on -//! [github](https://github.com/arrayfire/arrayfire-rust/issues). -//! -//! | arrayfire-rust crate | ArrayFire Upstream | -//! |:--------------------:|:------------------:| -//! | M.m.p1 | M.m.p2 | -//! -//! Only, Major(M) & Minor(m) version numbers need to match. *p1* and *p2* are patch/fix updates -//! for `arrayfire-rust` & `ArrayFire` respectively, and they don't need to match. -//! -//! Please go through our [tutorials](http://arrayfire.org/arrayfire-rust/book/index.html) book for -//! more explanations on how to use ArrayFire to speedup your code. -//! -//! Note that the public traits on arrayfire-rust crate aren't meant to be implemented for user -//! defined types. If attempted, rust compiler will throw an error. - -#![doc( - html_logo_url = "https://www.arrayfire.com/logos/arrayfire_logo_symbol.png", - html_favicon_url = "https://www.arrayfire.com/logos/arrayfire.ico", - html_root_url = "https://arrayfire.org/arrayfire-rust/arrayfire/index.html" -)] -#![warn(missing_docs)] -#![allow(non_camel_case_types)] - -#[macro_use] -extern crate lazy_static; - -pub use crate::core::*; -mod core; - -#[cfg(feature = "algorithm")] -pub use crate::algorithm::*; -#[cfg(feature = "algorithm")] -mod algorithm; - -#[cfg(feature = "blas")] -pub use crate::blas::*; -#[cfg(feature = "blas")] -mod blas; - -#[cfg(feature = "graphics")] -pub use crate::graphics::Window; -#[cfg(feature = "graphics")] -mod graphics; - -#[cfg(feature = "image")] -pub use crate::image::*; -#[cfg(feature = "image")] -mod image; - -#[cfg(feature = "lapack")] -pub use crate::lapack::*; -#[cfg(feature = "lapack")] -mod lapack; - -#[cfg(feature = "ml")] -pub use crate::ml::*; -#[cfg(feature = "ml")] -mod ml; - -#[cfg(feature = "signal")] -pub use crate::signal::*; -#[cfg(feature = "signal")] -mod signal; - -#[cfg(feature = "sparse")] -pub use crate::sparse::*; -#[cfg(feature = "sparse")] -mod sparse; - -#[cfg(feature = "statistics")] -pub use crate::statistics::*; -#[cfg(feature = "statistics")] -mod statistics; - -#[cfg(feature = "vision")] -pub use crate::vision::*; -#[cfg(feature = "vision")] -mod vision; - -// headers that are not exposed through rust wrapper are given follows: -// compatible.h -// constants.h -// complex.h -// cuda.h -// opencl.h diff --git a/src/ml/mod.rs b/src/ml/mod.rs deleted file mode 100644 index b36e8ba77..000000000 --- a/src/ml/mod.rs +++ /dev/null @@ -1,140 +0,0 @@ -use super::core::{ - af_array, dim_t, AfError, Array, ConvGradientType, Dim4, HasAfEnum, RealFloating, HANDLE_ERROR, -}; - -use libc::{c_int, c_uint}; - -extern "C" { - fn af_convolve2_nn( - out: *mut af_array, - signal: af_array, - filter: af_array, - stride_dims: c_uint, - strides: *const dim_t, - padding_dim: c_uint, - paddings: *const dim_t, - dilation_dim: c_uint, - dilations: *const dim_t, - ) -> c_int; - - fn af_convolve2_gradient_nn( - out: *mut af_array, - incoming_gradient: af_array, - original_signal: af_array, - original_filter: af_array, - convolved_output: af_array, - stride_dims: c_uint, - strides: *const dim_t, - padding_dims: c_uint, - paddings: *const dim_t, - dilation_dims: c_uint, - dilations: *const dim_t, - grad_type: c_uint, - ) -> c_int; -} - -/// Convolution Integral for two dimensional data -/// -/// This version of convolution is consistent with the machine learning formulation -/// that will spatially convolve a filter on 2-dimensions against a signal. Multiple -/// signals and filters can be batched against each other. Furthermore, the signals -/// and filters can be multi-dimensional however their dimensions must match. Usually, -/// this is the forward pass convolution in ML -/// -/// Example: -/// -/// Signals with dimensions: d0 x d1 x d2 x Ns -/// -/// Filters with dimensions: d0 x d1 x d2 x Nf -/// -/// Resulting Convolution: d0 x d1 x Nf x Ns -/// -/// # Parameters -/// -/// - `signal` is the input signal -/// - `filter` is convolution filter -/// - `strides` are distance between consecutive elements along each dimension for original convolution -/// - `padding` specifies padding width along each dimension for original convolution -/// - `dilation` specifies filter dilation along each dimension for original convolution -/// -/// # Return Values -/// -/// Convolved Array -pub fn convolve2_nn( - signal: &Array, - filter: &Array, - strides: Dim4, - padding: Dim4, - dilation: Dim4, -) -> Array -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_convolve2_nn( - &mut temp as *mut af_array, - signal.get(), - filter.get(), - 2, - strides.get().as_ptr() as *const dim_t, - 2, - padding.get().as_ptr() as *const dim_t, - 2, - dilation.get().as_ptr() as *const dim_t, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Backward pass gradient of 2D convolution -/// -/// # Parameters -/// -/// - `incoming_gradient` gradients to be distributed in backwards pass -/// - `original_signal` input signal to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N ) -/// - `original_filter` input filter to forward pass of convolution assumed structure of input is ( d0 x d1 x d2 x N ) -/// - `convolved_output` output from forward pass of convolution -/// - `strides` are distance between consecutive elements along each dimension for original convolution -/// - `padding` specifies padding width along each dimension for original convolution -/// - `dilation` specifies filter dilation along each dimension for original convolution -/// - `grad_type` specifies which gradient to return -/// -/// # Return Values -/// -/// Gradient Array w.r.t input generated from [convolve2_nn](./fn.convolve2_nn.html) -#[allow(clippy::too_many_arguments)] -pub fn convolve2_gradient_nn( - incoming_grad: &Array, - original_signal: &Array, - original_filter: &Array, - convolved_output: &Array, - strides: Dim4, - padding: Dim4, - dilation: Dim4, - grad_type: ConvGradientType, -) -> Array -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_convolve2_gradient_nn( - &mut temp as *mut af_array, - incoming_grad.get(), - original_signal.get(), - original_filter.get(), - convolved_output.get(), - 2, - strides.get().as_ptr() as *const dim_t, - 2, - padding.get().as_ptr() as *const dim_t, - 2, - dilation.get().as_ptr() as *const dim_t, - grad_type as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} diff --git a/src/signal/mod.rs b/src/signal/mod.rs deleted file mode 100644 index 1a1529a20..000000000 --- a/src/signal/mod.rs +++ /dev/null @@ -1,1105 +0,0 @@ -use super::core::{ - af_array, dim_t, AfError, Array, ComplexFloating, ConvDomain, ConvMode, FloatingPoint, - HasAfEnum, InterpType, RealFloating, HANDLE_ERROR, -}; - -use libc::{c_double, c_float, c_int, c_uint, size_t}; -use num::Complex; - -extern "C" { - fn af_approx1( - out: *mut af_array, - inp: af_array, - pos: af_array, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx1_v2( - out: *mut af_array, - inp: af_array, - pos: af_array, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx1_uniform( - out: *mut af_array, - inp: af_array, - pos: af_array, - interp_dim: c_int, - idx_start: c_double, - idx_step: c_double, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx1_uniform_v2( - out: *mut af_array, - inp: af_array, - pos: af_array, - interp_dim: c_int, - idx_start: c_double, - idx_step: c_double, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx2( - out: *mut af_array, - inp: af_array, - pos0: af_array, - pos1: af_array, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx2_v2( - out: *mut af_array, - inp: af_array, - pos0: af_array, - pos1: af_array, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx2_uniform( - out: *mut af_array, - inp: af_array, - pos0: af_array, - interp_dim0: c_int, - idx_start_dim0: c_double, - idx_step_dim0: c_double, - pos1: af_array, - interp_dim1: c_int, - idx_start_dim1: c_double, - idx_step_dim1: c_double, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_approx2_uniform_v2( - out: *mut af_array, - inp: af_array, - pos0: af_array, - interp_dim0: c_int, - idx_start_dim0: c_double, - idx_step_dim0: c_double, - pos1: af_array, - interp_dim1: c_int, - idx_start_dim1: c_double, - idx_step_dim1: c_double, - method: c_uint, - off_grid: c_float, - ) -> c_int; - - fn af_set_fft_plan_cache_size(cache_size: size_t) -> c_int; - - fn af_fft(out: *mut af_array, arr: af_array, nfac: c_double, odim0: dim_t) -> c_int; - - fn af_fft2( - out: *mut af_array, - arr: af_array, - nfac: c_double, - odim0: dim_t, - odim1: dim_t, - ) -> c_int; - - fn af_fft3( - out: *mut af_array, - arr: af_array, - nfac: c_double, - odim0: dim_t, - odim1: dim_t, - odim2: dim_t, - ) -> c_int; - - fn af_ifft(out: *mut af_array, arr: af_array, nfac: c_double, odim0: dim_t) -> c_int; - - fn af_ifft2( - out: *mut af_array, - arr: af_array, - nfac: c_double, - odim0: dim_t, - odim1: dim_t, - ) -> c_int; - - fn af_ifft3( - out: *mut af_array, - arr: af_array, - nfac: c_double, - odim0: dim_t, - odim1: dim_t, - odim2: dim_t, - ) -> c_int; - - fn af_fft_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - fn af_fft2_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - fn af_fft3_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - fn af_ifft_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - fn af_ifft2_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - fn af_ifft3_inplace(arr: *mut af_array, nfac: c_double) -> c_int; - - fn af_fft_r2c(out: *mut af_array, arr: af_array, nfac: c_double, pad0: dim_t) -> c_int; - fn af_fft2_r2c( - out: *mut af_array, - arr: af_array, - nfac: c_double, - pad0: dim_t, - pad1: dim_t, - ) -> c_int; - fn af_fft3_r2c( - out: *mut af_array, - arr: af_array, - nfac: c_double, - pad0: dim_t, - pad1: dim_t, - pad2: dim_t, - ) -> c_int; - - fn af_fft_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int; - fn af_fft2_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int; - fn af_fft3_c2r(out: *mut af_array, input: af_array, nfac: c_double, is_odd: bool) -> c_int; - - fn af_convolve1(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int; - fn af_convolve2(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int; - fn af_convolve3(out: *mut af_array, s: af_array, f: af_array, m: c_uint, d: c_uint) -> c_int; - fn af_convolve2_sep( - o: *mut af_array, - c: af_array, - r: af_array, - s: af_array, - m: c_uint, - ) -> c_int; - fn af_fft_convolve1(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int; - fn af_fft_convolve2(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int; - fn af_fft_convolve3(out: *mut af_array, s: af_array, f: af_array, m: c_uint) -> c_int; - fn af_fir(out: *mut af_array, b: af_array, x: af_array) -> c_int; - fn af_iir(out: *mut af_array, b: af_array, a: af_array, x: af_array) -> c_int; -} - -/// Perform signal interpolation for 1d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `pos` Array contains the interpolation locations -/// - `method` indicates the type of interpolation method that be used. It is of type enum -/// [InterpType](./enum.InterpType.html) -/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds -/// -/// # Return Values -/// -/// An Array with interpolated values -pub fn approx1( - input: &Array, - pos: &Array

, - method: InterpType, - off_grid: f32, -) -> Array -where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_approx1( - &mut temp as *mut af_array, - input.get(), - pos.get(), - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Same as [approx1](./fn.approx1.html) but uses existing Array as output -pub fn approx1_v2( - output: &mut Array, - input: &Array, - pos: &Array

, - method: InterpType, - off_grid: f32, -) where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let err_val = unsafe { - af_approx1_v2( - output.get() as *mut af_array, - input.get(), - pos.get(), - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Perform signal interpolation for 1d signals along specified dimension -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `pos` Array contains the interpolation locations -/// - `interp_dim` is the dimension along which interpolation is performed -/// - `start` is the first index along `interp_dim` -/// - `step` is the uniform spacing value between subsequent indices along `interp_dim` -/// - `method` indicates the type of interpolation method that be used. It is of type enum -/// [InterpType](./enum.InterpType.html) -/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds -/// -/// # Return Values -/// -/// An Array with interpolated values -pub fn approx1_uniform( - input: &Array, - pos: &Array

, - interp_dim: i32, - start: f64, - step: f64, - method: InterpType, - off_grid: f32, -) -> Array -where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_approx1_uniform( - &mut temp as *mut af_array, - input.get(), - pos.get(), - interp_dim, - start, - step, - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Same as [approx1_uniform](./fn.approx1_uniform.html) but uses existing Array as output -#[allow(clippy::too_many_arguments)] -pub fn approx1_uniform_v2( - output: &mut Array, - input: &Array, - pos: &Array

, - interp_dim: i32, - start: f64, - step: f64, - method: InterpType, - off_grid: f32, -) where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let err_val = unsafe { - af_approx1_uniform_v2( - output.get() as *mut af_array, - input.get(), - pos.get(), - interp_dim, - start, - step, - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Perform signal interpolation for 2d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `pos0` Array contains the interpolation locations for first dimension -/// - `pos1` Array contains the interpolation locations for second dimension -/// - `method` indicates the type of interpolation method that be used. It is of type enum -/// [InterpType](./enum.InterpType.html) -/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds -/// -/// # Return Values -/// -/// An Array with interpolated values -pub fn approx2( - input: &Array, - pos0: &Array

, - pos1: &Array

, - method: InterpType, - off_grid: f32, -) -> Array -where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_approx2( - &mut temp as *mut af_array, - input.get(), - pos0.get(), - pos1.get(), - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Same as [approx2](./fn.approx2.html) but uses existing Array as output -pub fn approx2_v2( - output: &mut Array, - input: &Array, - pos0: &Array

, - pos1: &Array

, - method: InterpType, - off_grid: f32, -) where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let err_val = unsafe { - af_approx2_v2( - output.get() as *mut af_array, - input.get(), - pos0.get(), - pos1.get(), - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Perform signal interpolation for 2d signals along a specified dimension -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `pos0` Array contains the interpolation locations for first dimension -/// - `interp_dim0` is the dimension along which interpolation is performed -/// - `start0` is the first index along `interp_dim0` -/// - `step0` is the uniform spacing value between subsequent indices along `interp_dim0` -/// - `pos1` Array contains the interpolation locations for second dimension -/// - `interp_dim0` is the dimension along which interpolation is performed -/// - `start0` is the first index along `interp_dim1` -/// - `step0` is the uniform spacing value between subsequent indices along `interp_dim1` -/// - `method` indicates the type of interpolation method that be used. It is of type enum -/// [InterpType](./enum.InterpType.html) -/// - `off_grid` is the value that will set in the output Array when certain index is out of bounds -/// -/// # Return Values -/// -/// An Array with interpolated values -#[allow(clippy::too_many_arguments)] -pub fn approx2_uniform( - input: &Array, - pos0: &Array

, - interp_dim0: i32, - start0: f64, - step0: f64, - pos1: &Array

, - interp_dim1: i32, - start1: f64, - step1: f64, - method: InterpType, - off_grid: f32, -) -> Array -where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_approx2_uniform( - &mut temp as *mut af_array, - input.get(), - pos0.get(), - interp_dim0, - start0, - step0, - pos1.get(), - interp_dim1, - start1, - step1, - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Same as [approx2_uniform](./fn.approx2_uniform.html) but uses existing Array as output -#[allow(clippy::too_many_arguments)] -pub fn approx2_uniform_v2( - output: &mut Array, - input: &Array, - pos0: &Array

, - interp_dim0: i32, - start0: f64, - step0: f64, - pos1: &Array

, - interp_dim1: i32, - start1: f64, - step1: f64, - method: InterpType, - off_grid: f32, -) where - T: HasAfEnum + FloatingPoint, - P: HasAfEnum + RealFloating, -{ - let err_val = unsafe { - af_approx2_uniform_v2( - output.get() as *mut af_array, - input.get(), - pos0.get(), - interp_dim0, - start0, - step0, - pos1.get(), - interp_dim1, - start1, - step1, - method as c_uint, - off_grid, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Set fft plan cache size -/// -/// Though this is a low overhead function, it is advised not to change -/// the fft plan cache size a mid program execution unless that is what -/// you intend to do. -pub fn set_fft_plan_cache_size(cache_size: usize) { - let err_val = unsafe { af_set_fft_plan_cache_size(cache_size as size_t) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// Fast fourier transform for 1d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signals - used for either truncating or padding the input -/// signals -/// -/// # Return Values -/// -/// Transformed Array -pub fn fft(input: &Array, norm_factor: f64, odim0: i64) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_fft(&mut temp as *mut af_array, input.get(), norm_factor, odim0) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Fast fourier transform for 2d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input -/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input -/// -/// # Return Values -/// -/// Transformed Array -pub fn fft2( - input: &Array, - norm_factor: f64, - odim0: i64, - odim1: i64, -) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_fft2( - &mut temp as *mut af_array, - input.get(), - norm_factor, - odim0, - odim1, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Fast fourier transform for 3d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input -/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input -/// - `odim2` is the length of output signal third dimension - used for either truncating or padding the input -/// -/// # Return Values -/// -/// Transformed Array -pub fn fft3( - input: &Array, - norm_factor: f64, - odim0: i64, - odim1: i64, - odim2: i64, -) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_fft3( - &mut temp as *mut af_array, - input.get(), - norm_factor, - odim0, - odim1, - odim2, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inverse fast fourier transform for 1d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signals - used for either truncating or padding the input -/// signals -/// -/// # Return Values -/// -/// Transformed Array -pub fn ifft(input: &Array, norm_factor: f64, odim0: i64) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_ifft(&mut temp as *mut af_array, input.get(), norm_factor, odim0) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inverse fast fourier transform for 2d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input -/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input -/// -/// # Return Values -/// -/// Transformed Array -pub fn ifft2( - input: &Array, - norm_factor: f64, - odim0: i64, - odim1: i64, -) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_ifft2( - &mut temp as *mut af_array, - input.get(), - norm_factor, - odim0, - odim1, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Inverse fast fourier transform for 3d signals -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor with which the input is scaled before the -/// transformation is applied -/// - `odim0` is the length of output signal first dimension - used for either truncating or padding the input -/// - `odim1` is the length of output signal second dimension - used for either truncating or padding the input -/// - `odim2` is the length of output signal third dimension - used for either truncating or padding the input -/// -/// # Return Values -/// -/// Transformed Array -pub fn ifft3( - input: &Array, - norm_factor: f64, - odim0: i64, - odim1: i64, - odim2: i64, -) -> Array -where - T: HasAfEnum + FloatingPoint, - ::ComplexOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_ifft3( - &mut temp as *mut af_array, - input.get(), - norm_factor, - odim0, - odim1, - odim2, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! conv_func_def { - ($doc_str: expr, $fn_name:ident, $ffi_name: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `signal` is the input signal - /// - `filter` is the signal that shall be flipped for convolution operation - /// - `mode` indicates if the convolution should be expanded or not(where output size - /// equals input). It takes a value of type [ConvMode](./enum.ConvMode.html) - /// - `domain` indicates if the convolution should be performed in frequencey or spatial - /// domain. It takes a value of type [ConvDomain](./enum.ConvDomain.html) - /// - ///# Return Values - /// - /// Convolved Array - pub fn $fn_name( - signal: &Array, - filter: &Array, - mode: ConvMode, - domain: ConvDomain, - ) -> Array - where - T: HasAfEnum, - F: HasAfEnum, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut temp as *mut af_array, - signal.get(), - filter.get(), - mode as c_uint, - domain as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -conv_func_def!("1d convolution", convolve1, af_convolve1); -conv_func_def!("2d convolution", convolve2, af_convolve2); -conv_func_def!("3d convolution", convolve3, af_convolve3); - -/// Separable convolution for 2d signals -/// -/// # Parameters -/// -/// - `cfilt` is the filter to be applied along coloumns -/// - `rfilt` is the filter to be applied along rows -/// - `signal` is the input signal -/// - `mode` indicates if the convolution should be expanded or not(where output size equals input) -/// -/// # Return Values -/// -/// The convolved Array -pub fn convolve2_sep( - cfilt: &Array, - rfilt: &Array, - signal: &Array, - mode: ConvMode, -) -> Array -where - T: HasAfEnum, - F: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_convolve2_sep( - &mut temp as *mut af_array, - cfilt.get(), - rfilt.get(), - signal.get(), - mode as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! fft_conv_func_def { - ($doc_str: expr, $fn_name:ident, $ffi_name: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `signal` is the input signal - /// - `filter` is the signal that shall be used for convolution operation - /// - `mode` indicates if the convolution should be expanded or not(where output size - /// equals input). It takes values of type [ConvMode](./enum.ConvMode.html) - /// - ///# Return Values - /// - /// Convolved Array - pub fn $fn_name(signal: &Array, filter: &Array, mode: ConvMode) -> Array - where - T: HasAfEnum, - F: HasAfEnum, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - $ffi_name( - &mut temp as *mut af_array, - signal.get(), - filter.get(), - mode as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -fft_conv_func_def!( - "1d convolution using fast-fourier transform", - fft_convolve1, - af_fft_convolve1 -); -fft_conv_func_def!( - "2d convolution using fast-fourier transform", - fft_convolve2, - af_fft_convolve2 -); -fft_conv_func_def!( - "3d convolution using fast-fourier transform", - fft_convolve3, - af_fft_convolve3 -); - -/// Finite impulse filter -/// -/// # Parameters -/// -/// - `b` is the Array containing the coefficients of the filter -/// - `x` is the input signal to filter -/// -/// # Return Values -/// -/// Filtered Array -pub fn fir(b: &Array, x: &Array) -> Array -where - B: HasAfEnum, - X: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_fir(&mut temp as *mut af_array, b.get(), x.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Infinite impulse response filter -/// -/// # Parameters -/// -/// - `b` is the Array containing the feedforward coefficients -/// - `a` is the Array containing the feedback coefficients -/// - `x` is the input signal to filter -/// -/// # Return Values -/// -/// Filtered Array -pub fn iir(b: &Array, a: &Array, x: &Array) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_iir(&mut temp as *mut af_array, b.get(), a.get(), x.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// In place 1d dimensional Fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn fft_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_fft_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// In place 2d dimensional Fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn fft2_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_fft2_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// In place 3d dimensional Fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn fft3_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_fft3_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// In place 1d dimensional inverse fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn ifft_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_ifft_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// In place 2d dimensional inverse fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn ifft2_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_ifft2_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// In place 3d dimensional inverse fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor -pub fn ifft3_inplace(input: &mut Array, norm_factor: f64) -where - T: HasAfEnum + ComplexFloating, -{ - let err_val = unsafe { af_ifft3_inplace(input.get() as *mut af_array, norm_factor) }; - HANDLE_ERROR(AfError::from(err_val)); -} - -/// 1d Real to Complex fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `pad0` is the padding along 0th dimension of Array -/// -/// # Return Values -/// -/// Complex Array -pub fn fft_r2c(input: &Array, norm_factor: f64, pad0: i64) -> Array> -where - T: HasAfEnum + RealFloating, - Complex: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_fft_r2c(&mut temp as *mut af_array, input.get(), norm_factor, pad0) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// 2d Real to Complex fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `pad0` is the padding along 0th dimension of Array -/// - `pad1` is the padding along 1st dimension of Array -/// -/// # Return Values -/// -/// Complex Array -pub fn fft2_r2c(input: &Array, norm_factor: f64, pad0: i64, pad1: i64) -> Array> -where - T: HasAfEnum + RealFloating, - Complex: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_fft2_r2c( - &mut temp as *mut af_array, - input.get(), - norm_factor, - pad0, - pad1, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// 3d Real to Complex fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `pad0` is the padding along 0th dimension of Array -/// - `pad1` is the padding along 1st dimension of Array -/// - `pad2` is the padding along 2nd dimension of Array -/// -/// # Return Values -/// -/// Complex Array -pub fn fft3_r2c( - input: &Array, - norm_factor: f64, - pad0: i64, - pad1: i64, - pad2: i64, -) -> Array> -where - T: HasAfEnum + RealFloating, - Complex: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_fft3_r2c( - &mut temp as *mut af_array, - input.get(), - norm_factor, - pad0, - pad1, - pad2, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// 1d Complex to Real fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `is_odd` signifies if the output should be even or odd size -/// -/// # Return Values -/// -/// Complex Array -pub fn fft_c2r(input: &Array, norm_factor: f64, is_odd: bool) -> Array -where - T: HasAfEnum + ComplexFloating, - ::BaseType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_fft_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// 2d Complex to Real fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `is_odd` signifies if the output should be even or odd size -/// -/// # Return Values -/// -/// Complex Array -pub fn fft2_c2r(input: &Array, norm_factor: f64, is_odd: bool) -> Array -where - T: HasAfEnum + ComplexFloating, - ::BaseType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_fft2_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// 3d Complex to Real fast fourier transform -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `norm_factor` is the normalization factor to be applied before fft is applied -/// - `is_odd` signifies if the output should be even or odd size -/// -/// # Return Values -/// -/// Complex Array -pub fn fft3_c2r(input: &Array, norm_factor: f64, is_odd: bool) -> Array -where - T: HasAfEnum + ComplexFloating, - ::BaseType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_fft3_c2r(&mut temp as *mut af_array, input.get(), norm_factor, is_odd) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} diff --git a/src/sparse/mod.rs b/src/sparse/mod.rs deleted file mode 100644 index 58bf2fc21..000000000 --- a/src/sparse/mod.rs +++ /dev/null @@ -1,355 +0,0 @@ -use super::core::{ - af_array, dim_t, AfError, Array, FloatingPoint, HasAfEnum, SparseFormat, HANDLE_ERROR, -}; - -use libc::{c_int, c_uint, c_void}; - -extern "C" { - fn af_create_sparse_array( - out: *mut af_array, - nRows: dim_t, - nCols: dim_t, - vals: af_array, - rowIdx: af_array, - colIdx: af_array, - stype: c_uint, - ) -> c_int; - - fn af_create_sparse_array_from_ptr( - out: *mut af_array, - nRows: dim_t, - nCols: dim_t, - nNZ: dim_t, - values: *const c_void, - rowIdx: *const c_int, - colIdx: *const c_int, - aftype: c_uint, - stype: c_uint, - src: c_uint, - ) -> c_int; - - fn af_create_sparse_array_from_dense( - out: *mut af_array, - dense: af_array, - stype: c_uint, - ) -> c_int; - - fn af_sparse_convert_to(out: *mut af_array, input: af_array, dstStrge: c_uint) -> c_int; - - fn af_sparse_to_dense(out: *mut af_array, sparse: af_array) -> c_int; - - fn af_sparse_get_info( - vals: *mut af_array, - rIdx: *mut af_array, - cIdx: *mut af_array, - stype: *mut c_uint, - input: af_array, - ) -> c_int; - - fn af_sparse_get_values(out: *mut af_array, input: af_array) -> c_int; - - fn af_sparse_get_row_idx(out: *mut af_array, input: af_array) -> c_int; - - fn af_sparse_get_col_idx(out: *mut af_array, input: af_array) -> c_int; - - fn af_sparse_get_nnz(out: *mut dim_t, input: af_array) -> c_int; - - fn af_sparse_get_storage(out: *mut c_uint, input: af_array) -> c_int; -} - -/// Create sprase matrix from arrays -/// -/// This function converts [Array](./struct.Array.html) of `values` into sparse array -/// of `format` sparse format using arrays `row_indices` and `col_indices`. -/// -/// # Parameters -/// -/// - `rows` is the number of rows in the dense matrix -/// - `cols` is the number of columns in the dense matrix -/// - `values` is the \ref af::array containing the non-zero elements -/// `of the matrix -/// - `row_indices` is the row indices for the sparse array -/// - `col_indices` is the column indices for the sparse array -/// - `format` is the storage format of the sparse array -/// -/// # Return Values -/// -/// Array with data in given sparse format -/// -/// # Note -/// -/// This function only uses references of the input arrays to create the -/// sparse data structure and does not perform deep copies. -pub fn sparse( - rows: u64, - cols: u64, - values: &Array, - row_indices: &Array, - col_indices: &Array, - format: SparseFormat, -) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_sparse_array( - &mut temp as *mut af_array, - rows as dim_t, - cols as dim_t, - values.get(), - row_indices.get(), - col_indices.get(), - format as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Create sprase matrix from data on host memory -/// -/// This function converts host array `values` into sparse array of `format` sparse -/// format using host arrays `row_indices` and `col_indices`. -/// -/// # Parameters -/// -/// - `rows` is the number of rows in the dense matrix -/// - `cols` is the number of columns in the dense matrix -/// - `nzz` is the number of non zero elements in the dense matrix -/// - `values` is the \ref af::array containing the non-zero elements -/// `of the matrix -/// - `row_indices` is the row indices for the sparse array -/// - `col_indices` is the column indices for the sparse array -/// - `format` is the storage format of the sparse array -/// -/// # Return Values -/// -/// Array with data in given sparse format -/// -/// # Note -/// -/// The rules for deep copy/shallow copy/reference are the same as for creating a -/// regular [Array](./struct.Array.html). -pub fn sparse_from_host( - rows: u64, - cols: u64, - nzz: u64, - values: &[T], - row_indices: &[i32], - col_indices: &[i32], - format: SparseFormat, -) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let aftype = T::get_af_dtype(); - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_sparse_array_from_ptr( - &mut temp as *mut af_array, - rows as dim_t, - cols as dim_t, - nzz as dim_t, - values.as_ptr() as *const c_void, - row_indices.as_ptr() as *const c_int, - col_indices.as_ptr() as *const c_int, - aftype as c_uint, - format as c_uint, - 1, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Convert dense array to sparse array -/// -/// # Parameters -/// -/// - `dense` is the dense format array -/// - `format` is the target sparse format -/// -/// # Return Values -/// -/// Sparse Array -pub fn sparse_from_dense(dense: &Array, format: SparseFormat) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_create_sparse_array_from_dense(&mut temp as *mut af_array, dense.get(), format as c_uint) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Convert between sparse formats -/// -/// # Parameters -/// -/// - `input` is the input sparse array -/// - `format` is the target sparse format -/// -/// # Return Values -/// -/// Sparse Array in targe sparse format. -pub fn sparse_convert_to(input: &Array, format: SparseFormat) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { af_sparse_convert_to(&mut temp as *mut af_array, input.get(), format as c_uint) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Convert sparse array to dense array -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Dense Array -pub fn sparse_to_dense(input: &Array) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sparse_to_dense(&mut temp as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Get sparse Array information -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// A tuple of values, row indices, column indices Arrays and SparseFormat enum. -pub fn sparse_get_info(input: &Array) -> (Array, Array, Array, SparseFormat) -where - T: HasAfEnum + FloatingPoint, -{ - let mut val: af_array = std::ptr::null_mut(); - let mut row: af_array = std::ptr::null_mut(); - let mut col: af_array = std::ptr::null_mut(); - let mut stype: u32 = 0; - let err_val = unsafe { - af_sparse_get_info( - &mut val as *mut af_array, - &mut row as *mut af_array, - &mut col as *mut af_array, - &mut stype as *mut c_uint, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - ( - val.into(), - row.into(), - col.into(), - SparseFormat::from(stype), - ) -} - -/// Get values of sparse Array -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Sparse array values -pub fn sparse_get_values(input: &Array) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut val: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sparse_get_values(&mut val as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - val.into() -} - -/// Get row indices Array -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Array with row indices values of sparse Array -pub fn sparse_get_row_indices(input: &Array) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut val: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sparse_get_row_idx(&mut val as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - val.into() -} - -/// Get cololumn indices Array -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Array with coloumn indices values of sparse Array -pub fn sparse_get_col_indices(input: &Array) -> Array -where - T: HasAfEnum + FloatingPoint, -{ - let mut val: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_sparse_get_col_idx(&mut val as *mut af_array, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - val.into() -} - -/// Get number of non-zero elements in sparse array -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Number of non-zero elements of sparse Array -pub fn sparse_get_nnz(input: &Array) -> i64 { - let mut count: i64 = 0; - - let err_val = unsafe { af_sparse_get_nnz(&mut count as *mut dim_t, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - - count -} - -/// Get sparse format -/// -/// # Parameters -/// -/// - `input` is the sparse array -/// -/// # Return Values -/// -/// Sparse array format -pub fn sparse_get_format(input: &Array) -> SparseFormat { - let mut stype: u32 = 0; - - let err_val = unsafe { af_sparse_get_storage(&mut stype as *mut c_uint, input.get()) }; - HANDLE_ERROR(AfError::from(err_val)); - - SparseFormat::from(stype) -} diff --git a/src/statistics/mod.rs b/src/statistics/mod.rs deleted file mode 100644 index 97fffd65d..000000000 --- a/src/statistics/mod.rs +++ /dev/null @@ -1,640 +0,0 @@ -use super::core::{ - af_array, dim_t, AfError, Array, CovarianceComputable, HasAfEnum, MedianComputable, - RealFloating, RealNumber, TopkFn, VarianceBias, HANDLE_ERROR, -}; - -use libc::{c_double, c_int, c_uint}; - -extern "C" { - fn af_mean(out: *mut af_array, arr: af_array, dim: dim_t) -> c_int; - fn af_median(out: *mut af_array, arr: af_array, dim: dim_t) -> c_int; - - fn af_mean_weighted(out: *mut af_array, arr: af_array, wts: af_array, dim: dim_t) -> c_int; - fn af_var_weighted(out: *mut af_array, arr: af_array, wts: af_array, dim: dim_t) -> c_int; - - fn af_mean_all(real: *mut c_double, imag: *mut c_double, arr: af_array) -> c_int; - fn af_median_all(real: *mut c_double, imag: *mut c_double, arr: af_array) -> c_int; - - fn af_mean_all_weighted( - real: *mut c_double, - imag: *mut c_double, - arr: af_array, - wts: af_array, - ) -> c_int; - fn af_var_all_weighted( - real: *mut c_double, - imag: *mut c_double, - arr: af_array, - wts: af_array, - ) -> c_int; - - fn af_corrcoef(real: *mut c_double, imag: *mut c_double, X: af_array, Y: af_array) -> c_int; - fn af_topk( - vals: *mut af_array, - idxs: *mut af_array, - arr: af_array, - k: c_int, - dim: c_int, - order: c_uint, - ) -> c_int; - - fn af_meanvar( - mean: *mut af_array, - var: *mut af_array, - input: af_array, - weights: af_array, - bias: c_uint, - dim: dim_t, - ) -> c_int; - fn af_var_v2(out: *mut af_array, arr: af_array, bias_kind: c_uint, dim: dim_t) -> c_int; - fn af_cov_v2(out: *mut af_array, X: af_array, Y: af_array, bias_kind: c_uint) -> c_int; - fn af_stdev_v2(out: *mut af_array, arr: af_array, bias_kind: c_uint, dim: dim_t) -> c_int; - fn af_var_all_v2( - real: *mut c_double, - imag: *mut c_double, - arr: af_array, - bias_kind: c_uint, - ) -> c_int; - fn af_stdev_all_v2( - real: *mut c_double, - imag: *mut c_double, - arr: af_array, - bias_kind: c_uint, - ) -> c_int; -} - -/// Find the median along a given dimension -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `dim` is dimension along which median has to be found -/// -///# Return Values -/// -/// An Array whose size is equal to input except along the dimension which -/// median needs to be found. Array size along `dim` will be reduced to one. -pub fn median(input: &Array, dim: i64) -> Array -where - T: HasAfEnum + MedianComputable, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_median(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -macro_rules! stat_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `input` is the input Array - /// - `dim` is dimension along which the current stat has to be computed - /// - ///# Return Values - /// - /// An Array whose size is equal to input except along the dimension which - /// the stat operation is performed. Array size along `dim` will be reduced to one. - pub fn $fn_name(input: &Array, dim: i64) -> Array - where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_fn(&mut temp as *mut af_array, input.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -stat_func_def!("Mean along specified dimension", mean, af_mean); - -macro_rules! stat_wtd_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `input` is the input Array - /// - `weights` Array has the weights to be used during the stat computation - /// - `dim` is dimension along which the current stat has to be computed - /// - ///# Return Values - /// - /// An Array whose size is equal to input except along the dimension which - /// the stat operation is performed. Array size along `dim` will be reduced to one. - pub fn $fn_name( - input: &Array, - weights: &Array, - dim: i64, - ) -> Array - where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, - W: HasAfEnum + RealFloating, - { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = - unsafe { $ffi_fn(&mut temp as *mut af_array, input.get(), weights.get(), dim) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() - } - }; -} - -stat_wtd_func_def!( - "Weighted mean along specified dimension", - mean_weighted, - af_mean_weighted -); -stat_wtd_func_def!( - "Weight variance along specified dimension", - var_weighted, - af_var_weighted -); - -/// Compute Variance along a specific dimension -/// -/// # Parameters -/// -/// - `arr` is the input Array -/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed -/// - `dim` is the dimension along which the variance is extracted -/// -/// # Return Values -/// -/// Array with variance of input Array `arr` along dimension `dim`. -/// -/// [1]: ./enum.VarianceBias.html -pub fn var_v2(arr: &Array, bias_kind: VarianceBias, dim: i64) -> Array -where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_var_v2( - &mut temp as *mut af_array, - arr.get(), - bias_kind as c_uint, - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Compute Variance along a specific dimension -/// -/// # Parameters -/// -/// - `arr` is the input Array -/// - `isbiased` is boolean denoting population variance(False) or Sample variance(True) -/// - `dim` is the dimension along which the variance is extracted -/// -/// # Return Values -/// -/// Array with variance of input Array `arr` along dimension `dim`. -#[deprecated(since = "3.8.0", note = "Please use var_v2 API")] -pub fn var(arr: &Array, isbiased: bool, dim: i64) -> Array -where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, -{ - var_v2( - arr, - if isbiased { - VarianceBias::SAMPLE - } else { - VarianceBias::POPULATION - }, - dim, - ) -} - -/// Compute covariance of two Arrays -/// -/// # Parameters -/// -/// - `x` is the first Array -/// - `y` is the second Array -/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed -/// -/// # Return Values -/// -/// An Array with Covariance values -/// -/// [1]: ./enum.VarianceBias.html -pub fn cov_v2(x: &Array, y: &Array, bias_kind: VarianceBias) -> Array -where - T: HasAfEnum + CovarianceComputable, - T::MeanOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_cov_v2( - &mut temp as *mut af_array, - x.get(), - y.get(), - bias_kind as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Compute covariance of two Arrays -/// -/// # Parameters -/// -/// - `x` is the first Array -/// - `y` is the second Array -/// - `isbiased` is boolean denoting if biased estimate should be taken(default: False) -/// -/// # Return Values -/// -/// An Array with Covariance values -#[deprecated(since = "3.8.0", note = "Please use cov_v2 API")] -pub fn cov(x: &Array, y: &Array, isbiased: bool) -> Array -where - T: HasAfEnum + CovarianceComputable, - T::MeanOutType: HasAfEnum, -{ - cov_v2( - x, - y, - if isbiased { - VarianceBias::SAMPLE - } else { - VarianceBias::POPULATION - }, - ) -} - -/// Compute Variance of all elements -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed -/// -/// # Return Values -/// -/// A tuple of 64-bit floating point values that has the variance of `input` Array. -/// -/// [1]: ./enum.VarianceBias.html -pub fn var_all_v2(input: &Array, bias_kind: VarianceBias) -> (f64, f64) { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_var_all_v2( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - bias_kind as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) -} - -/// Compute Variance of all elements -/// -/// # Parameters -/// -/// - `input` is the input Array -/// - `isbiased` is boolean denoting population variance(False) or sample variance(True) -/// -/// # Return Values -/// -/// A tuple of 64-bit floating point values that has the variance of `input` Array. -#[deprecated(since = "3.8.0", note = "Please use var_all_v2 API")] -pub fn var_all(input: &Array, isbiased: bool) -> (f64, f64) { - var_all_v2( - input, - if isbiased { - VarianceBias::SAMPLE - } else { - VarianceBias::POPULATION - }, - ) -} - -macro_rules! stat_all_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `input` is the input Array - /// - ///# Return Values - /// - /// A tuple of 64-bit floating point values with the stat values. - pub fn $fn_name(input: &Array) -> (f64, f64) { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - $ffi_fn( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) - } - }; -} - -stat_all_func_def!("Compute mean of all data", mean_all, af_mean_all); - -/// Compute median of all data -/// -///# Parameters -/// -/// - `input` is the input Array -/// -///# Return Values -/// -/// A tuple of 64-bit floating point values with the median -pub fn median_all(input: &Array) -> (f64, f64) -where - T: HasAfEnum + MedianComputable, -{ - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_median_all( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) -} - -macro_rules! stat_wtd_all_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_fn: ident) => { - #[doc=$doc_str] - /// - ///# Parameters - /// - /// - `input` is the input Array - /// - `weights` Array has the weights - /// - ///# Return Values - /// - /// A tuple of 64-bit floating point values with the stat values. - pub fn $fn_name(input: &Array, weights: &Array) -> (f64, f64) - where - T: HasAfEnum, - W: HasAfEnum + RealFloating, - { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - $ffi_fn( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - weights.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) - } - }; -} - -stat_wtd_all_func_def!( - "Compute weighted mean of all data", - mean_all_weighted, - af_mean_all_weighted -); -stat_wtd_all_func_def!( - "Compute weighted variance of all data", - var_all_weighted, - af_var_all_weighted -); - -/// Compute correlation coefficient -/// -/// # Parameters -/// -/// - `x` is the first Array -/// - `y` isthe second Array -/// -/// # Return Values -/// A tuple of 64-bit floating point values with the coefficients. -pub fn corrcoef(x: &Array, y: &Array) -> (f64, f64) -where - T: HasAfEnum + RealNumber, -{ - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_corrcoef( - &mut real as *mut c_double, - &mut imag as *mut c_double, - x.get(), - y.get(), - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) -} - -/// Find top k elements along a given dimension -/// -/// This function returns the top k values along a given dimension of the input -/// array. The indices along with their values are returned. -/// -/// If the input is a multi-dimensional array, the indices will be the index of -/// the value in that dimension. Order of duplicate values are not preserved. -/// -/// This function is optimized for small values of k. Currently, topk elements -/// can be found only along dimension 0. -/// -/// # Parameters -/// -/// - `input` is the values from which top k elements are to be retrieved -/// - `k` is the number of top elements to be retrieve -/// - `dim` is the dimension along which the retrieval operation has to performed -/// - `order` is an enum that can take values of type [TopkFn](./enum.TopkFn.html) -/// -/// # Return Values -/// -/// A tuple(couple) of Array's with the first Array containing the topk values -/// with the second Array containing the indices of the topk values in the input -/// data. -pub fn topk(input: &Array, k: u32, dim: i32, order: TopkFn) -> (Array, Array) -where - T: HasAfEnum, -{ - let mut t0: af_array = std::ptr::null_mut(); - let mut t1: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_topk( - &mut t0 as *mut af_array, - &mut t1 as *mut af_array, - input.get(), - k as c_int, - dim as c_int, - order as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (t0.into(), t1.into()) -} - -/// Calculate mean and variance in single API call -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `weights` Array has the weights to be used during the stat computation -/// - `bias` is type of bias used for variance calculation -/// - `dim` is dimension along which the current stat has to be computed -/// -///# Return Values -/// -/// A tuple of Arrays, whose size is equal to input except along the dimension which -/// the stat operation is performed. Array size along `dim` will be reduced to one. -/// -/// - First Array contains mean values -/// - Second Array contains variance values -pub fn meanvar( - input: &Array, - weights: &Array, - bias: VarianceBias, - dim: i64, -) -> (Array, Array) -where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, - W: HasAfEnum + RealFloating, -{ - let mut mean: af_array = std::ptr::null_mut(); - let mut var: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_meanvar( - &mut mean as *mut af_array, - &mut var as *mut af_array, - input.get(), - weights.get(), - bias as c_uint, - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (mean.into(), var.into()) -} - -/// Standard deviation along given axis -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed -/// - `dim` is dimension along which the current stat has to be computed -/// -///# Return Values -/// -/// An Array whose size is equal to input except along the dimension which -/// the stat operation is performed. Array size along `dim` will be reduced to one. -/// -/// [1]: ./enum.VarianceBias.html -pub fn stdev_v2(input: &Array, bias_kind: VarianceBias, dim: i64) -> Array -where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_stdev_v2( - &mut temp as *mut af_array, - input.get(), - bias_kind as c_uint, - dim, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Standard deviation along specified axis -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `dim` is dimension along which the current stat has to be computed -/// -///# Return Values -/// -/// An Array whose size is equal to input except along the dimension which -/// the stat operation is performed. Array size along `dim` will be reduced to one. -#[deprecated(since = "3.8.0", note = "Please use stdev_v2 API")] -pub fn stdev(input: &Array, dim: i64) -> Array -where - T: HasAfEnum, - T::MeanOutType: HasAfEnum, -{ - stdev_v2(input, VarianceBias::POPULATION, dim) -} - -/// Compute standard deviation of all data -/// -///# Parameters -/// -/// - `input` is the input Array -/// - `bias_kind` of type [VarianceBias][1] denotes the type of variane to be computed -/// -///# Return Values -/// -/// A tuple of 64-bit floating point values with the stat values. -/// -/// [1]: ./enum.VarianceBias.html -pub fn stdev_all_v2(input: &Array, bias_kind: VarianceBias) -> (f64, f64) { - let mut real: f64 = 0.0; - let mut imag: f64 = 0.0; - - let err_val = unsafe { - af_stdev_all_v2( - &mut real as *mut c_double, - &mut imag as *mut c_double, - input.get(), - bias_kind as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - (real, imag) -} - -/// Compute standard deviation of all data -/// -///# Parameters -/// -/// - `input` is the input Array -/// -///# Return Values -/// -/// A tuple of 64-bit floating point values with the stat values. -pub fn stdev_all(input: &Array) -> (f64, f64) { - stdev_all_v2(input, VarianceBias::POPULATION) -} diff --git a/src/vision/mod.rs b/src/vision/mod.rs deleted file mode 100644 index 35be91056..000000000 --- a/src/vision/mod.rs +++ /dev/null @@ -1,686 +0,0 @@ -use super::core::{ - af_array, af_features, dim_t, AfError, Array, HasAfEnum, HomographyType, ImageFilterType, - MatchType, RealFloating, HANDLE_ERROR, -}; - -use libc::{c_float, c_int, c_uint}; -use std::mem; - -// af_sift and af_gloh uses patented algorithms, so didn't add them -// they are NOT built using installer builds - -extern "C" { - fn af_create_features(feat: *mut af_features, num: dim_t) -> c_int; - fn af_retain_features(feat: *mut af_features, feat: af_features) -> c_int; - fn af_get_features_num(num: *mut dim_t, feat: af_features) -> c_int; - fn af_get_features_xpos(out: *mut af_array, feat: af_features) -> c_int; - fn af_get_features_ypos(out: *mut af_array, feat: af_features) -> c_int; - fn af_get_features_score(out: *mut af_array, feat: af_features) -> c_int; - fn af_get_features_orientation(out: *mut af_array, feat: af_features) -> c_int; - fn af_get_features_size(out: *mut af_array, feat: af_features) -> c_int; - fn af_release_features(feat: af_features) -> c_int; - - fn af_fast( - out: *mut af_features, - input: af_array, - thr: c_float, - arc_len: c_uint, - non_max: bool, - feature_ratio: c_float, - edge: c_uint, - ) -> c_int; - - fn af_harris( - out: *mut af_features, - input: af_array, - m: c_uint, - r: c_float, - s: c_float, - bs: c_uint, - k: c_float, - ) -> c_int; - - fn af_orb( - out: *mut af_features, - desc: *mut af_array, - arr: af_array, - fast_thr: c_float, - max_feat: c_uint, - scl_fctr: c_float, - levels: c_uint, - blur_img: bool, - ) -> c_int; - - fn af_hamming_matcher( - idx: *mut af_array, - dist: *mut af_array, - query: af_array, - train: af_array, - dist_dim: dim_t, - n_dist: c_uint, - ) -> c_int; - - fn af_nearest_neighbour( - idx: *mut af_array, - dist: *mut af_array, - q: af_array, - t: af_array, - dist_dim: dim_t, - n_dist: c_uint, - dist_type: c_int, - ) -> c_int; - - fn af_match_template( - out: *mut af_array, - search_img: af_array, - template_img: af_array, - mtype: c_uint, - ) -> c_int; - - fn af_susan( - feat: *mut af_features, - i: af_array, - r: c_uint, - d: c_float, - g: c_float, - f: c_float, - e: c_uint, - ) -> c_int; - - fn af_dog(out: *mut af_array, i: af_array, r1: c_int, r2: c_int) -> c_int; - - fn af_homography( - H: *mut af_array, - inliers: *mut c_int, - x_src: af_array, - y_src: af_array, - x_dst: af_array, - y_dst: af_array, - htype: c_uint, - inlier_thr: c_float, - iterations: c_uint, - otype: c_uint, - ) -> c_int; -} - -/// A set of Array objects (usually, used in Computer vision context) -/// -/// `Features` struct is used by computer vision functions -/// to return the outcome of their operation. Typically, such output -/// has the following Arrays: -/// -/// - X positions of the features -/// - Y positions of the features -/// - Scores of the features -/// - Orientations of the features -/// - Sizes of the features -/// -/// ## Sharing Across Threads -/// -/// While sharing this object with other threads, there is no need to wrap -/// this in an Arc object unless only one such object is required to exist. -/// The reason being that ArrayFire's internal details that are pointed to -/// by the features handle are appropriately reference counted in thread safe -/// manner. However, if these features are to be edited, then please do wrap -/// the object using a Mutex or Read-Write lock. -pub struct Features { - feat: af_features, -} - -unsafe impl Send for Features {} -unsafe impl Sync for Features {} - -macro_rules! feat_func_def { - ($doc_str: expr, $fn_name: ident, $ffi_name: ident) => { - #[doc=$doc_str] - pub fn $fn_name(&self) -> Array { - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { $ffi_name(&mut temp as *mut af_array, self.feat) }; - HANDLE_ERROR(AfError::from(err_val)); - - let temp_array: Array = temp.into(); - let retained = temp_array.clone(); - mem::forget(temp_array); - - retained - } - }; -} - -impl Features { - /// Create and return an object of type Features - /// - /// This object is basically a bunch of Arrays. - pub fn new(n: u64) -> Self { - let mut temp: af_features = std::ptr::null_mut(); - let err_val = unsafe { af_create_features(&mut temp as *mut af_features, n as dim_t) }; - HANDLE_ERROR(AfError::from(err_val)); - Self { feat: temp } - } - - /// Get total number of features found - pub fn num_features(&self) -> i64 { - let mut temp: i64 = 0; - - let err_val = unsafe { - af_get_features_num( - &mut temp as *mut dim_t, - self.feat as *const dim_t as af_features, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - - temp - } - - feat_func_def!("Get x coordinates Array", xpos, af_get_features_xpos); - feat_func_def!("Get y coordinates Array", ypos, af_get_features_ypos); - feat_func_def!("Get score Array", score, af_get_features_score); - feat_func_def!( - "Get orientation Array", - orientation, - af_get_features_orientation - ); - feat_func_def!("Get features size Array", size, af_get_features_size); -} - -impl Clone for Features { - fn clone(&self) -> Self { - let mut temp: af_features = std::ptr::null_mut(); - let ret_val = unsafe { af_retain_features(&mut temp as *mut af_features, self.feat) }; - HANDLE_ERROR(AfError::from(ret_val)); - Self { feat: temp } - } -} - -impl Drop for Features { - fn drop(&mut self) { - let ret_val = unsafe { af_release_features(self.feat) }; - HANDLE_ERROR(AfError::from(ret_val)); - } -} - -/// Fast feature detector -/// -/// A circle of radius 3 pixels, translating into a total of 16 pixels, is checked for sequential -/// segments of pixels much brighter or much darker than the central one. For a pixel p to be -/// considered a feature, there must exist a sequential segment of arc_length pixels in the circle -/// around it such that all are greather than (p + thr) or smaller than (p - thr). After all -/// features in the image are detected, if nonmax is true, the non-maximal suppression is applied, -/// checking all detected features and the features detected in its 8-neighborhood and discard it -/// if its score is non maximal. -/// -/// # Parameters -/// -/// - `input` - the input image Array -/// - `thr` - FAST threshold for which pixel of the circle around the center pixel is considered to -/// be greater or smaller -/// - `arc_len` - length of arc (or sequential segment) to be tested, must be within range [9-16] -/// - `non_max` - performs non-maximal supression if true -/// - `feat_ratio` - maximum ratio of features to detect, the maximum number of features is -/// calculated by `feature_ratio * num of elements`. The maximum number of features is not based on -/// the score, instead, features detected after the limit is reached are discarded. -/// - `edge` - is the length of the edges in the image to be discarded by FAST(minimum is 3, as the -/// radius of the circle) -/// -/// # Return Values -/// -/// This function returns an object of struct [Features](./struct.Features.html) containing Arrays -/// for x and y coordinates and score, while array oreientation is set to 0 as FAST does not -/// compute orientation. Size is set to 1 as FAST does not compute multiple scales. -pub fn fast( - input: &Array, - thr: f32, - arc_len: u32, - non_max: bool, - feat_ratio: f32, - edge: u32, -) -> Features -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_features = std::ptr::null_mut(); - let err_val = unsafe { - af_fast( - &mut temp as *mut af_features, - input.get(), - thr, - arc_len, - non_max, - feat_ratio, - edge, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - Features { feat: temp } -} - -/// Harris corner detector. -/// -/// Compute corners using the Harris corner detector approach. For each pixel, a small window is -/// used to calculate the determinant and trace of such a window, from which a response is -/// calculated. Pixels are considered corners if they are local maximas and have a high positive -/// response. -/// -/// # Parameters -/// -/// - `input` is the array containing a grayscale image (color images are not supported) -/// - `max_corners` is the maximum number of corners to keep, only retains those with highest Harris responses -/// - `min_response` is the minimum response in order for a corner to be retained, only used if max_corners = 0 -/// - `sigma` is the standard deviation of a circular window (its dimensions will be calculated according to the standard deviation), the covariation matrix will be calculated to a circular neighborhood of this standard deviation (only used when block_size == 0, must be >= 0.5f and <= 5.0f) -/// - `block_size` is square window size, the covariation matrix will be calculated to a square neighborhood of this size (must be >= 3 and <= 31) -/// - `k_thr` is the Harris constant, usually set empirically to 0.04f (must be >= 0.01f) -/// -/// # Return Values -/// -/// This function returns an object of struct [Features](./struct.Features.html) containing Arrays -/// for x and y coordinates and score, while array oreientation & size are set to 0 & 1, -/// respectively, since harris doesn't compute that information -pub fn harris( - input: &Array, - max_corners: u32, - min_response: f32, - sigma: f32, - block_size: u32, - k_thr: f32, -) -> Features -where - T: HasAfEnum + RealFloating, -{ - let mut temp: af_features = std::ptr::null_mut(); - let err_val = unsafe { - af_harris( - &mut temp as *mut af_features, - input.get(), - max_corners, - min_response, - sigma, - block_size, - k_thr, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - Features { feat: temp } -} - -/// ORB feature descriptor -/// -/// Extract ORB descriptors from FAST features that hold higher Harris responses. FAST does not -/// compute orientation, thus, orientation of features is calculated using the intensity centroid. -/// As FAST is also not multi-scale enabled, a multi-scale pyramid is calculated by downsampling -/// the input image multiple times followed by FAST feature detection on each scale. -/// -/// # Parameters -/// -/// - `input` - the input image Array -/// - `fast_thr` - FAST threshold for which a pixel of the circle around the central pixel is -/// considered to be brighter or darker -/// - `max_feat` - maximum number of features to hold -/// - `scl_fctr` - factor to downsample the input image, meaning that each level with hold prior -/// level dimensions divided by `scl_fctr` -/// - `levels` - number of levels to be computed for the image pyramid -/// - `blur_img` - blur image with a Gaussian filter with sigma=2 before computing descriptors to -/// increase robustness against noise if true -/// -/// # Return Values -/// -/// This function returns a tuple of [`Features`](./struct.Features.html) and [`Array`](./struct.Array.html). The features objects composed of Arrays for x and y coordinates, score, orientation and size of selected features. The Array object is a two dimensional Array of size Nx8 where N is number of selected features. -pub fn orb( - input: &Array, - fast_thr: f32, - max_feat: u32, - scl_fctr: f32, - levels: u32, - blur_img: bool, -) -> (Features, Array) -where - T: HasAfEnum + RealFloating, -{ - let mut f: af_features = std::ptr::null_mut(); - let mut d: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_orb( - &mut f as *mut af_features, - &mut d as *mut af_array, - input.get(), - fast_thr, - max_feat, - scl_fctr, - levels, - blur_img, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (Features { feat: f }, d.into()) -} - -/// Hamming feature matcher -/// -/// Calculates Hamming distances between two 2-dimensional arrays containing features, one of the -/// arrays containing the training data and the other the query data. One of the dimensions of the -/// both arrays must be equal among them, identifying the length of each feature. The other -/// dimension indicates the total number of features in each of the training and query arrays. Two -/// 1-dimensional arrays are created as results, one containg the smallest N distances of the query -/// array and another containing the indices of these distances in the training array. The -/// resulting 1-dimensional arrays have length equal to the number of features contained in the -/// query array. -/// -/// # Parameters -/// -/// - `query` - Array containing the data to be queried -/// - `train` - Array containing the data to be used as training data -/// - `dist_dims` - indicates the dimension to analyze for distance (the dimension indicated here -/// must be of equal length for both query and train arrays) -/// - `n_dist` - is the number of smallest distances to return (currently, only values <= 256 are supported) -/// -/// -/// # Return Values -/// -/// This function returns a tuple of [Array](./struct.Array.html)'s. -/// -/// First Array is an array of MxN size, where M is equal to the number of query features and N is -/// equal to n_dist. The value at position IxJ indicates the index of the Jth smallest distance to -/// the Ith query value in the train data array. the index of the Ith smallest distance of the Mth -/// query. -/// -/// Second Array is an array of MxN size, where M is equal to the number of query features and N is -/// equal to n_dist. The value at position IxJ indicates the Hamming distance of the Jth smallest -/// distance to the Ith query value in the train data array. -pub fn hamming_matcher( - query: &Array, - train: &Array, - dist_dims: i64, - n_dist: u32, -) -> (Array, Array) -where - T: HasAfEnum + ImageFilterType, - T::AggregateOutType: HasAfEnum, -{ - let mut idx: af_array = std::ptr::null_mut(); - let mut dist: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_hamming_matcher( - &mut idx as *mut af_array, - &mut dist as *mut af_array, - query.get(), - train.get(), - dist_dims, - n_dist, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (idx.into(), dist.into()) -} - -/// Nearest Neighbour. -/// -/// Calculates nearest distances between two 2-dimensional arrays containing features based on the -/// type of distance computation chosen. Currently, AF_SAD (sum of absolute differences), AF_SSD -/// (sum of squared differences) and AF_SHD (hamming distance) are supported. One of the arrays -/// containing the training data and the other the query data. One of the dimensions of the both -/// arrays must be equal among them, identifying the length of each feature. The other dimension -/// indicates the total number of features in each of the training and query arrays. Two -/// 1-dimensional arrays are created as results, one containg the smallest N distances of the query -/// array and another containing the indices of these distances in the training array. The resulting -/// 1-dimensional arrays have length equal to the number of features contained in the query array. -/// -/// # Parameters -/// -/// - `query` is the array containing the data to be queried -/// - `train` is the array containing the data used as training data -/// - `dist_dim` indicates the dimension to analyze for distance (the dimension indicated here must be of equal length for both query and train arrays) -/// - `n_dist` is the number of smallest distances to return (currently, only values <= 256 are supported) -/// - `dist_type` is the distance computation type. Currently [`MatchType::SAD`](./enum.MatchType.html), [`MatchType::SSD`](./enum.MatchType.html), and [`MatchType::SHD`](./enum.MatchType.html) are supported. -/// -/// # Return Values -/// -/// A tuple of Arrays. -/// -/// The first Array is is an array of MxN size, where M is equal to the number of query features -/// and N is equal to `n_dist`. The value at position IxJ indicates the index of the Jth smallest -/// distance to the Ith query value in the train data array. the index of the Ith smallest distance -/// of the Mth query. -/// -/// The second Array is is an array of MxN size, where M is equal to the number of query features -/// and N is equal to `n_dist`. The value at position IxJ indicates the distance of the Jth smallest -/// distance to the Ith query value in the train data array based on the `dist_type` chosen. -pub fn nearest_neighbour( - query: &Array, - train: &Array, - dist_dim: i64, - n_dist: u32, - dist_type: MatchType, -) -> (Array, Array) -where - T: HasAfEnum + ImageFilterType, - T::AggregateOutType: HasAfEnum, -{ - let mut idx: af_array = std::ptr::null_mut(); - let mut dist: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_nearest_neighbour( - &mut idx as *mut af_array, - &mut dist as *mut af_array, - query.get(), - train.get(), - dist_dim, - n_dist, - dist_type as c_int, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (idx.into(), dist.into()) -} - -/// Image matching -/// -/// Template matching is an image processing technique to find small patches of an image which -/// match a given template image. A more in depth discussion on the topic can be found -/// [here](https://en.wikipedia.org/wiki/Template_matching). -/// -/// # Parameters -/// -/// - `search_img` is an array with image data -/// - `template_img` is the template we are looking for in the image -/// - `mtype` is metric that should be used to calculate the disparity between window in the image and the template image. It can be one of the values defined by the enum [MatchType](./enum.MatchType.html). -/// # Return Values -/// -/// This function returns an Array with disparity values for the window starting at corresponding pixel position. -pub fn match_template( - search_img: &Array, - template_img: &Array, - mtype: MatchType, -) -> Array -where - T: HasAfEnum + ImageFilterType, - T::AbsOutType: HasAfEnum, -{ - match mtype { - MatchType::NCC | MatchType::ZNCC | MatchType::SHD => HANDLE_ERROR(AfError::ERR_ARG), - _ => (), // Do nothing valid matching type - }; - - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_match_template( - &mut temp as *mut af_array, - search_img.get(), - template_img.get(), - mtype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// SUSAN corner detector. -/// -/// SUSAN is an acronym standing for Smallest Univalue Segment Assimilating Nucleus. This method -/// places a circular disc over the pixel to be tested (a.k.a nucleus) to compute the corner -/// measure of that corresponding pixel. The region covered by the circular disc is M, and a pixel -/// in this region is represented by m⃗ ∈M where m⃗ 0 is the nucleus. Every pixel in the region is -/// compared to the nucleus using the following comparison function: -/// -/// c(m⃗ )=e^−((I(m⃗)−I(m⃗_0))/t)^6 -/// -/// where t is radius of the region, I is the brightness of the pixel. -/// -/// Response of SUSAN operator is given by the following equation: -/// -/// R(M) = g−n(M) if n(M) < g -/// -/// R(M) = 0 otherwise, -/// -/// where n(M)=∑c(m⃗) m⃗∈M, g is named the geometric threshold and n is the number of pixels in the -/// mask which are within t of the nucleus. -/// -/// Importance of the parameters, t and g is explained below: -/// -/// - t determines how similar points have to be to the nucleusbefore they are considered to be a -/// part of the univalue segment -/// - g determines the minimum size of the univalue segment. For a large enough g, SUSAN operator -/// becomes an edge dectector. -/// -/// # Parameters -/// -/// - `input` is input grayscale/intensity image -/// - `radius` is the nucleus radius for each pixel neighborhood -/// - `diff_thr` is intensity difference threshold a.k.a **t** from equations in description -/// - `geom_thr` is the geometric threshold -/// - `feature_ratio` is maximum number of features that will be returned by the function -/// - `edge` indicates how many pixels width area should be skipped for corner detection -/// -/// # Return Values -/// An object of type [Features](./struct.Features.html) composed of arrays for x and y coordinates, score, orientation and size of selected features. -pub fn susan( - input: &Array, - radius: u32, - diff_thr: f32, - geom_thr: f32, - feature_ratio: f32, - edge: u32, -) -> Features -where - T: HasAfEnum + ImageFilterType, -{ - let mut temp: af_features = std::ptr::null_mut(); - let err_val = unsafe { - af_susan( - &mut temp as *mut af_features, - input.get(), - radius, - diff_thr, - geom_thr, - feature_ratio, - edge, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - Features { feat: temp } -} - -/// Difference of Gaussians. -/// -/// Given an image, this function computes two different versions of smoothed input image using the -/// difference smoothing parameters and subtracts one from the other and returns the result. -/// -/// # Parameters -/// -/// - `input` is the input image -/// - `radius1` is the radius of the first gaussian kernel -/// - `radius2` is the radius of the second gaussian kernel -/// -/// # Return Values -/// -/// Difference of smoothed inputs - An Array. -pub fn dog(input: &Array, radius1: i32, radius2: i32) -> Array -where - T: HasAfEnum + ImageFilterType, - T::AbsOutType: HasAfEnum, -{ - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { af_dog(&mut temp as *mut af_array, input.get(), radius1, radius2) }; - HANDLE_ERROR(AfError::from(err_val)); - temp.into() -} - -/// Homography estimation -/// -/// Homography estimation find a perspective transform between two sets of 2D points. -/// Currently, two methods are supported for the estimation, RANSAC (RANdom SAmple Consensus) -/// and LMedS (Least Median of Squares). Both methods work by randomly selecting a subset -/// of 4 points of the set of source points, computing the eigenvectors of that set and -/// finding the perspective transform. The process is repeated several times, a maximum of -/// times given by the value passed to the iterations arguments for RANSAC (for the CPU -/// backend, usually less than that, depending on the quality of the dataset, but for CUDA -/// and OpenCL backends the transformation will be computed exactly the amount of times -/// passed via the iterations parameter), the returned value is the one that matches the -/// best number of inliers, which are all of the points that fall within a maximum L2 -/// distance from the value passed to the inlier_thr argument. -/// -/// # Parameters -/// -/// - `x_src` is the x coordinates of the source points. -/// - `y_src` is the y coordinates of the source points. -/// - `x_dst` is the x coordinates of the destination points. -/// - `y_dst` is the y coordinates of the destination points. -/// - `htype` can be AF_HOMOGRAPHY_RANSAC, for which a RANdom SAmple Consensus will be used to evaluate the homography quality (e.g., number of inliers), or AF_HOMOGRAPHY_LMEDS, which will use Least Median of Squares method to evaluate homography quality -/// - `inlier_thr` - if htype is AF_HOMOGRAPHY_RANSAC, this parameter will five the maximum L2-distance for a point to be considered an inlier. -/// - `iterations` is the maximum number of iterations when htype is AF_HOMOGRAPHY_RANSAC and backend is CPU,if backend is CUDA or OpenCL, iterations is the total number of iterations, an iteration is a selection of 4 random points for which the homography is estimated and evaluated for number of inliers. -/// - `otype` is the array type for the homography output. -/// -/// # Return Values -/// -/// Returns a tuple of Array and int. -/// -/// - `H` is a 3x3 array containing the estimated homography. -/// - `inliers` is the number of inliers that the homography was estimated to comprise, in the case that htype is AF_HOMOGRAPHY_RANSAC, a higher inlier_thr value will increase the estimated inliers. Note that if the number of inliers is too low, it is likely that a bad homography will be returned. -pub fn homography( - x_src: &Array, - y_src: &Array, - x_dst: &Array, - y_dst: &Array, - htype: HomographyType, - inlier_thr: f32, - iterations: u32, -) -> (Array, i32) -where - OutType: HasAfEnum + RealFloating, -{ - let otype = OutType::get_af_dtype(); - - let mut inliers: i32 = 0; - let mut temp: af_array = std::ptr::null_mut(); - let err_val = unsafe { - af_homography( - &mut temp as *mut af_array, - &mut inliers as *mut c_int, - x_src.get(), - y_src.get(), - x_dst.get(), - y_dst.get(), - htype as c_uint, - inlier_thr, - iterations, - otype as c_uint, - ) - }; - HANDLE_ERROR(AfError::from(err_val)); - (temp.into(), inliers) -} - -#[cfg(test)] -mod tests { - use crate::randu; - - #[test] - #[should_panic] - fn check_invalid_matchtype() { - crate::core::set_device(0); - let a = randu!(f32; 10, 10); - let b = randu!(f32; 2, 2); - super::match_template(&a, &b, crate::MatchType::NCC); - super::match_template(&a, &b, crate::MatchType::ZNCC); - super::match_template(&a, &b, crate::MatchType::SHD); - } -} diff --git a/storage.js b/storage.js new file mode 100644 index 000000000..318275ed3 --- /dev/null +++ b/storage.js @@ -0,0 +1 @@ +var resourcesSuffix="";var darkThemes=["dark","ayu"];var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var settingsDataset=(function(){var settingsElement=document.getElementById("default-settings");if(settingsElement===null){return null}var dataset=settingsElement.dataset;if(dataset===undefined){return null}return dataset})();function getSettingValue(settingName){var current=getCurrentValue('rustdoc-'+settingName);if(current!==null){return current}if(settingsDataset!==null){var def=settingsDataset[settingName.replace(/-/g,'_')];if(def!==undefined){return def}}return null}var localStoredTheme=getSettingValue("theme");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;var i;if(reversed!==true){for(i=0;i=0;--i){if(func(arr[i])===true){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function hasOwnProperty(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function usableLocalStorage(){if(typeof Storage==="undefined"){return false}try{return window.localStorage!==null&&window.localStorage!==undefined}catch(err){return false}}function updateLocalStorage(name,value){if(usableLocalStorage()){localStorage[name]=value}else{}}function getCurrentValue(name){if(usableLocalStorage()&&localStorage[name]!==undefined){return localStorage[name]}return null}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(saveTheme===true){updateLocalStorage("rustdoc-theme",newTheme)}if(styleElem.href===newHref){return}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href)})}onEach(savedHref,function(el){if(el===newHref){found=true;return true}});if(found===true){styleElem.href=newHref}}function useSystemTheme(value){if(value===undefined){value=true}updateLocalStorage("rustdoc-use-system-theme",value);var toggle=document.getElementById("use-system-theme");if(toggle&&toggle instanceof HTMLInputElement){toggle.checked=value}}var updateSystemTheme=(function(){if(!window.matchMedia){return function(){let cssTheme=getComputedStyle(document.documentElement).getPropertyValue('content');switchTheme(currentTheme,mainTheme,JSON.parse(cssTheme)||light,true)}}var mql=window.matchMedia("(prefers-color-scheme: dark)");function handlePreferenceChange(mql){if(getSettingValue("use-system-theme")!=="false"){var lightTheme=getSettingValue("preferred-light-theme")||"light";var darkTheme=getSettingValue("preferred-dark-theme")||"dark";if(mql.matches){switchTheme(currentTheme,mainTheme,darkTheme,true)}else{switchTheme(currentTheme,mainTheme,lightTheme,true)}}}mql.addListener(handlePreferenceChange);return function(){handlePreferenceChange(mql)}})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("rustdoc-preferred-dark-theme",localStoredTheme)}updateSystemTheme()}else{switchTheme(currentTheme,mainTheme,getSettingValue("theme")||"light",false)} \ No newline at end of file diff --git a/tests/error_handler.rs b/tests/error_handler.rs deleted file mode 100644 index 7b1bcb12d..000000000 --- a/tests/error_handler.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::thread; - -use ::arrayfire::*; - -macro_rules! implement_handler { - ($fn_name:ident) => { - pub fn $fn_name(error_code: AfError) { - match error_code { - AfError::SUCCESS => {} /* No-op */ - _ => panic!("Error message: {}", error_code), - } - } - }; -} - -implement_handler!(handler_sample1); -implement_handler!(handler_sample2); -implement_handler!(handler_sample3); -implement_handler!(handler_sample4); - -#[allow(unused_must_use)] -#[test] -fn check_error_handler_mutation() { - let children = (0..4) - .map(|i| { - thread::Builder::new() - .name(format!("child {}", i + 1)) - .spawn(move || { - let target_device = i % arrayfire::device_count(); - println!( - "Thread {:?} 's target device is {}", - thread::current(), - target_device - ); - match i { - 0 => register_error_handler(Callback::new(handler_sample1)), - 1 => register_error_handler(Callback::new(handler_sample2)), - 2 => register_error_handler(Callback::new(handler_sample3)), - 3 => register_error_handler(Callback::new(handler_sample4)), - _ => panic!("Impossible scenario"), - } - }) - .expect("Failed to launch a thread") - }) - .collect::>(); - - for c in children { - c.join(); - } -} diff --git a/tests/scalar_arith.rs b/tests/scalar_arith.rs deleted file mode 100644 index a80fc2aec..000000000 --- a/tests/scalar_arith.rs +++ /dev/null @@ -1,18 +0,0 @@ -use ::arrayfire::*; - -#[test] -fn check_scalar_arith() { - let dims = Dim4::new(&[5, 5, 1, 1]); - let a = randu::(dims); - let s: f32 = 2.0; - let scalar_as_lhs = s * &a; - let scalar_as_rhs = &a * s; - let c = constant(s, dims); - let no_scalars = a * c; - let scalar_res_comp = eq(&scalar_as_lhs, &scalar_as_rhs, false); - let res_comp = eq(&scalar_as_lhs, &no_scalars, false); - let scalar_res = all_true_all(&scalar_res_comp); - let res = all_true_all(&res_comp); - - assert!(scalar_res.0 == res.0); -} diff --git a/theme.js b/theme.js new file mode 100644 index 000000000..8f9c49a42 --- /dev/null +++ b/theme.js @@ -0,0 +1 @@ +var themes=document.getElementById("theme-choices");var themePicker=document.getElementById("theme-picker");function showThemeButtonState(){themes.style.display="block";themePicker.style.borderBottomRightRadius="0";themePicker.style.borderBottomLeftRadius="0"}function hideThemeButtonState(){themes.style.display="none";themePicker.style.borderBottomRightRadius="3px";themePicker.style.borderBottomLeftRadius="3px"}function switchThemeButtonState(){if(themes.style.display==="block"){hideThemeButtonState()}else{showThemeButtonState()}};function handleThemeButtonsBlur(e){var active=document.activeElement;var related=e.relatedTarget;if(active.id!=="theme-picker"&&(!active.parentNode||active.parentNode.id!=="theme-choices")&&(!related||(related.id!=="theme-picker"&&(!related.parentNode||related.parentNode.id!=="theme-choices")))){hideThemeButtonState()}}themePicker.onclick=switchThemeButtonState;themePicker.onblur=handleThemeButtonsBlur;["ayu","dark","light"].forEach(function(item){var but=document.createElement("button");but.textContent=item;but.onclick=function(el){switchTheme(currentTheme,mainTheme,item,true);useSystemTheme(false)};but.onblur=handleThemeButtonsBlur;themes.appendChild(but)}) \ No newline at end of file diff --git a/tutorials-book/.gitignore b/tutorials-book/.gitignore deleted file mode 100644 index 7585238ef..000000000 --- a/tutorials-book/.gitignore +++ /dev/null @@ -1 +0,0 @@ -book diff --git a/tutorials-book/book.toml b/tutorials-book/book.toml deleted file mode 100644 index 6cf472978..000000000 --- a/tutorials-book/book.toml +++ /dev/null @@ -1,11 +0,0 @@ -[book] -authors = ["Pradeep Garigipati"] -language = "en" -multilingual = false -src = "src" -title = "Rust Wrapper for ArrayFire HPC Library" - -[output.html] -theme = "src/theme" -mathjax-support = true -default-theme = "Coal" diff --git a/tutorials-book/src/SUMMARY.md b/tutorials-book/src/SUMMARY.md deleted file mode 100644 index 39a2437f5..000000000 --- a/tutorials-book/src/SUMMARY.md +++ /dev/null @@ -1,11 +0,0 @@ -# Summary - -- [Getting Started](./getting_started.md) -- [Introduction to Vectorization](./vectorization.md) -- [Array and Matrix Manipulation](./array_and_matrix_manipulation.md) -- [Indexing](./indexing.md) -- [Configuring ArrayFire Runtime Environment](./configuring_arrayfire_environment.md) -- [Interoperability with CUDA](./cuda-interop.md) -- [Interoperability with OpenCL](./opencl-interop.md) -- [Multhi-Threading](./multi-threading.md) -- [Serialization & Deserialization](./serde.md) diff --git a/tutorials-book/src/array_and_matrix_manipulation.md b/tutorials-book/src/array_and_matrix_manipulation.md deleted file mode 100644 index 99d28732d..000000000 --- a/tutorials-book/src/array_and_matrix_manipulation.md +++ /dev/null @@ -1,306 +0,0 @@ -# Array and Matrix Manipulation - -ArrayFire provides several different methods for manipulating arrays and matrices. The functionality -includes: - -* [moddims()](#moddims) - change the dimensions of an array without changing the data -* [flat()](#flat) - flatten an array to one dimension -* [flip()](#flip) - flip an array along a dimension -* [join()](#join) - join up to 4 arrays -* [reorder()](#reorder) - changes the dimension order within the array -* [shift()](#shift) - shifts data along a dimension -* [tile()](#tile) - repeats an array along a dimension -* [transpose()](#transpose) - performs a matrix transpose - -Below we provide several examples of these functions and their use. - -### moddims() - -The [moddims][1] function changes the dimensions of an array without changing its data or order. -Note that this function modifies only the _metadata_ associated with the array. It does not modify -the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and -then back to a 8x1: - -```rust,noplaypen -a [8 1 1 1] - 1.0000 - 2.0000 - 1.0000 - 2.0000 - 1.0000 - 2.0000 - 1.0000 - 2.0000 - -let new_dims = Dim4::new(&[2, 4, 1, 1]); -moddims(&a, new_dims) -[2 4 1 1] - 1.0000 1.0000 1.0000 1.0000 - 2.0000 2.0000 2.0000 2.0000 - -let out = moddims(&a, a.elements(), 1, 1, 1); -[8 1 1 1] - 1.0000 - 2.0000 - 1.0000 - 2.0000 - 1.0000 - 2.0000 - 1.0000 - 2.0000 -``` - -### flat() - -The [flat][2] function flattens an array to one dimension: - -``` -a [3 3 1 1] - 1.0000 4.0000 7.0000 - 2.0000 5.0000 8.0000 - 3.0000 6.0000 9.0000 - -flat(&a) -[9 1 1 1] - 1.0000 - 2.0000 - 3.0000 - 4.0000 - 5.0000 - 6.0000 - 7.0000 - 8.0000 - 9.0000 -``` - -### flip() - -The [flip][3] function flips the contents of an array along a chosen dimension. In the example -below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. -across rows) axes: - -```rust,noplaypen -a [5 2 1 1] - 1.0000 6.0000 - 2.0000 7.0000 - 3.0000 8.0000 - 4.0000 9.0000 - 5.0000 10.0000 - -flip(a, 0) [5 2 1 1] - 5.0000 10.0000 - 4.0000 9.0000 - 3.0000 8.0000 - 2.0000 7.0000 - 1.0000 6.0000 - -flip(a, 1) [5 2 1 1] - 6.0000 1.0000 - 7.0000 2.0000 - 8.0000 3.0000 - 9.0000 4.0000 - 10.0000 5.0000 -``` - -### join() - -The [join][4], [join\_many][5] functions can be used to join arrays along a specific dimension. - -Here is an example of how to use join an array to itself: - -```rust,noplaypen -a [5 1 1 1] - 1.0000 - 2.0000 - 3.0000 - 4.0000 - 5.0000 - -join(0, a, a) [10 1 1 1] - 1.0000 - 2.0000 - 3.0000 - 4.0000 - 5.0000 - 1.0000 - 2.0000 - 3.0000 - 4.0000 - 5.0000 - -join(1, a, a) [5 2 1 1] - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 - 4.0000 4.0000 - 5.0000 5.0000 -``` - -### reorder() - -The [reorder][6] function modifies the order of data within an array by exchanging data according to -the change in dimensionality. The linear ordering of data within the array is preserved. - -```rust,noplaypen -a [2 2 3 1] - 1.0000 3.0000 - 2.0000 4.0000 - - 1.0000 3.0000 - 2.0000 4.0000 - - 1.0000 3.0000 - 2.0000 4.0000 - - -reorder(&a, 1, 0, 2) -[2 2 3 1] //equivalent to a transpose - 1.0000 2.0000 - 3.0000 4.0000 - - 1.0000 2.0000 - 3.0000 4.0000 - - 1.0000 2.0000 - 3.0000 4.0000 - - -reorder(&a, 2, 0, 1) -[3 2 2 1] - 1.0000 2.0000 - 1.0000 2.0000 - 1.0000 2.0000 - - 3.0000 4.0000 - 3.0000 4.0000 - 3.0000 4.0000 -``` - -### shift() - -The [shift][7] function shifts data in a circular buffer fashion along a chosen dimension. Consider -the following example: - -```rust,noplaypen -a [3 5 1 1] - 0.0000 0.0000 0.0000 0.0000 0.0000 - 3.0000 4.0000 5.0000 1.0000 2.0000 - 3.0000 4.0000 5.0000 1.0000 2.0000 - -shift(&a, 0, 2 ) -[3 5 1 1] - 0.0000 0.0000 0.0000 0.0000 0.0000 - 1.0000 2.0000 3.0000 4.0000 5.0000 - 1.0000 2.0000 3.0000 4.0000 5.0000 - -shift(&a, -1, 2 ) -[3 5 1 1] - 1.0000 2.0000 3.0000 4.0000 5.0000 - 1.0000 2.0000 3.0000 4.0000 5.0000 - 0.0000 0.0000 0.0000 0.0000 0.0000 -``` - -### tile() - -The [tile][8] function repeats an array along the specified dimension. For example below we show how -to tile an array along the zeroth and first dimensions of an array: - -```rust,noplaypen -a [3 1 1 1] - 1.0000 - 2.0000 - 3.0000 - -// Repeat array a twice in the zeroth dimension -tile(&a, 2) -[6 1 1 1] - 1.0000 - 2.0000 - 3.0000 - 1.0000 - 2.0000 - 3.0000 - -// Repeat array a twice along both the zeroth and first dimensions -tile(&a, 2, 2) -[6 2 1 1] - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 - -// Repeat array a twice along the first and three times along the second -// dimension. -let tile_dims = Dim4::new(&[1, 2, 3, 1]); -tile(a, tile_dims) [3 2 3 1] - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 - - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 - - 1.0000 1.0000 - 2.0000 2.0000 - 3.0000 3.0000 -``` - -### transpose() - -The [transpose][9] function performs a standard matrix transpose. The input array must have the -dimensions of a 2D-matrix. - -```rust,noplaypen -a [3 3 1 1] - 1.0000 3.0000 3.0000 - 2.0000 1.0000 3.0000 - 2.0000 2.0000 1.0000 - -transpose(&a, False) //Second parameter to be used for conjugate transpose -[3 3 1 1] - 1.0000 2.0000 2.0000 - 3.0000 1.0000 2.0000 - 3.0000 3.0000 1.0000 -``` - -### Combining functions to enumerate grid coordinates - -By using a combination of the functions, one can quickly code complex manipulation patterns with -a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis -goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small -combination of the above functions. - -```rust,noplaypen -let a = iota::(Dim4::new(&[3, 1, 1, 1]), - Dim4::new(&[1, 3, 1, 1])); -let b = transpose(&a, false); -let coords = join(1, &flat(&a), &flat(&b)); -print(&coords); -``` - -The output for a `[3 3 1 1]` matrix will be the following. -```rust,noplaypen -[9 2 1 1] - 0 0 - 1 0 - 2 0 - 0 1 - 1 1 - 2 1 - 0 2 - 1 2 - 2 2 -``` - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.moddims.html -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.flat.html -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.flip.html -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.join.html -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.join_many.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.reorder.html -[7]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.shift.html -[8]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.tile.html -[9]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.transpose.html diff --git a/tutorials-book/src/configuring_arrayfire_environment.md b/tutorials-book/src/configuring_arrayfire_environment.md deleted file mode 100644 index 7db86482d..000000000 --- a/tutorials-book/src/configuring_arrayfire_environment.md +++ /dev/null @@ -1,143 +0,0 @@ -# Configuring Arrayfire Environment - -Following are the list of environment and runtime configurations that will help enhance your -experience with ArrayFire. - -## AF\_PATH - -This is the path with ArrayFire gets installed, ie. the includes and libs are present in this -directory. You can use this variable to add include paths and libraries to your projects. - -## AF\_PRINT\_ERRORS - -When `AF\_PRINT\_ERRORS` is set to 1, the exceptions thrown are more verbose and detailed. This -helps in locating the exact failure. - -``` -AF_PRINT_ERRORS=1 ./myprogram -``` - -## AF\_CUDA\_DEFAULT\_DEVICE - -Use this variable to set the default CUDA device. Valid values for this variable are the device -identifiers shown when [info][1] is run. - -``` -AF_CUDA_DEFAULT_DEVICE=1 ./myprogram -``` - -Note: [set\_device][2] call in the source code will take precedence over this variable. - -## AF\_OPENCL\_DEFAULT\_DEVICE - -Use this variable to set the default OpenCL device. Valid values for this variable are the device -identifiers shown when [info][1] is run. - -``` -AF_OPENCL_DEFAULT_DEVICE=1 ./myprogram -``` - -Note: [set\_device][2] call in the source code will take precedence over this variable. - -## AF\_OPENCL\_DEFAULT\_DEVICE\_TYPE - -Use this variable to set the default OpenCL device type. Valid values for this variable are: CPU, -GPU, ACC (Accelerators). When set, the first device of the specified type is chosen as default device. - -``` -AF_OPENCL_DEFAULT_DEVICE_TYPE=CPU ./myprogram -``` - -Note: `AF_OPENCL_DEFAULT_DEVICE` and [set\_device][2] takes precedence over this variable. - -## AF\_OPENCL\_DEVICE\_TYPE - -Use this variable to only choose OpenCL devices of specified type. Valid values for this variable are: - -- ALL: All OpenCL devices. (Default behavior). -- CPU: CPU devices only. -- GPU: GPU devices only. -- ACC: Accelerator devices only. - -When set, the remaining OpenCL device types are ignored by the OpenCL backend. - -``` -AF_OPENCL_DEVICE_TYPE=CPU ./myprogram -``` - -## AF\_OPENCL\_CPU\_OFFLOAD - -When ArrayFire runs on devices with unified memory with the host (ie. `CL_DEVICE_HOST_UNIFIED_MENORY` -is true for the device) then certain functions are offloaded to run on the CPU using mapped buffers. - -ArrayFire takes advantage of fast libraries such as MKL while spending no time copying memory from -device to host. The device memory is mapped to a host pointer which can be used in the offloaded -functions. - -This functionality can be disabled by using the environment variable `AF_OPENCL_CPU_OFFLOAD=0`. - -The default bevaior of this has changed in version 3.4. Prior to v3.4, CPU Offload functionality was -used only when the user set `AF_OPENCL_CPU_OFFLOAD=1` and disabled otherwise. From v3.4 onwards, CPU -Offload is enabled by default and is disabled only when `AF_OPENCL_CPU_OFFLOAD=0` is set. - -## AF\_OPENCL\_SHOW\_BUILD\_INFO - -This variable is useful when debuggin OpenCL kernel compilation failures. When this variable is set -to 1, and an error occurs during a OpenCL kernel compilation, then the log and kernel are printed to screen. - -## AF\_DISABLE\_GRAPHICS - -Setting this variable to 1 will disable window creation when graphics functions are being called. -Disabling window creation will disable all other graphics calls at runtime. This is a useful -when running code on servers and systems without displays. When graphics calls are run on such -machines, they will print warning about window creation failing. To suppress those calls, set this -variable. - -## AF\_SYNCHRONOUS\_CALLS - -When this environment variable is set to 1, ArrayFire will execute all functions synchronously. - -## AF\_SHOW\_LOAD\_PATH - -When using the Unified backend, if this variable is set to 1, it will show the path where the ArrayFire -backend libraries are loaded from. - -If the libraries are loaded from system paths, such as PATH or LD\_LIBRARY\_PATH etc, then it will -print "system path". If the libraries are loaded from other paths, then those paths are shown in full. - -## AF\_MEM\_DEBUG - -When AF\_MEM\_DEBUG is set to 1 (or anything not equal to 0), the caching mechanism in the memory manager -is disabled. The device buffers are allocated using native functions as needed and freed when going out -of scope. When the environment variable is not set, it is treated to be non zero. - -``` -AF_MEM_DEBUG=1 ./myprogram -``` - -## AF\_MAX\_BUFFERS - -When AF\_MAX\_BUFFERS is set, this environment variable specifies the maximum number of buffers -allocated before garbage collection kicks in. Please note that the total number of buffers that -can exist simultaneously can be higher than this number. This variable tells the garbage collector -that it should free any available buffers immediately if the treshold is reached. When not set, -the default value is 1000. - -## AF\_OPENCL\_MAX\_JIT\_LEN - -When set, this environment variable specifies the maximum height of the OpenCL JIT tree after -which evaluation is forced. The default value, as of v3.4, is 50 on OSX, 100 everywhere else. -This value was 20 for older versions. - -## AF\_CUDA\_MAX\_JIT\_LEN - -When set, this environment variable specifies the maximum height of the CUDA JIT tree after -which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions. - -## AF\_CPU\_MAX\_JIT\_LEN - -When set, this environment variable specifies the maximum length of the CPU JIT tree after -which evaluation is forced. The default value, as of v3.4, 100. This value was 20 for older versions. - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.info.html -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_device.html diff --git a/tutorials-book/src/cuda-interop.md b/tutorials-book/src/cuda-interop.md deleted file mode 100644 index 1d244ff02..000000000 --- a/tutorials-book/src/cuda-interop.md +++ /dev/null @@ -1,105 +0,0 @@ -# Interoperability with CUDA - -{{#include interop_excerpts.md:1:4}} - -ArrayFire manages its own memory, runs within its own CUDA stream, and creates custom IDs for -devices. As such, most of the interoperability functions focus on reducing potential synchronization -conflicts between ArrayFire and CUDA. - -## Basics - -{{#include interop_excerpts.md:6:7}} - -| Function | Purpose | -|------------------------------------|-----------------------------------------------------------| -| [Array::new\_from\_device\_ptr][1] | Construct an ArrayFire [Array][14] from device memory | -| [Array::device\_ptr][2] | Obtain a pointer to the device memory (implies `lock()`) | -| [Array::lock][3] | Removes ArrayFire's control of a device memory pointer | -| [Array::unlock][4] | Restores ArrayFire's control over a device memory pointer | -| [get\_device][5] | Gets the current ArrayFire device ID | -| [set\_device][6] | Switches ArrayFire to the specified device | -| [get\_device\_native\_id][7] | Fetches CUDA deviceID for a given ArrayFire device ID | -| [set\_device\_native\_id][8] | Switches active device to the specified CUDA device ID | -| [get\_stream][9] | Get the current CUDA stream used by ArrayFire | - -## Using custom CUDA kernels in existing ArrayFire application - -By default, ArrayFire manages its own memory and operates in its own CUDA stream. Thus there is a -slight amount of bookkeeping that needs to be done in order to integrate your custom CUDA kernel. - -Ideally, we recommend using ArrayFire's CUDA stream to launch your custom kernels. However, this -is currently not possible due to limitation on [RustaCUDA][10] not being to able to wrap an -existing cudaStream\_t/CUstream\_t objects. The current work around is to create a stream of your -own and launch the kernel on it. - -Notice that since ArrayFire and your kernels are not sharing the same CUDA stream, there is a need -to perform explicit synchronization before launching kernel on your stream that depends on the -computation carried out by ArrayFire earlier. This extra step is unnecessary once the above stated -limiation of RustaCUDA's stream is eliminated. - -This process is best illustrated with a fully worked example: -```rust -{{#include ../../cuda-interop/examples/custom_kernel.rs}} -``` - -## Adding ArrayFire to existing CUDA Application - -{{#include interop_excerpts.md:9:15}} - - 1. Finish any pending CUDA operations (e.g. cudaDeviceSynchronize() or similar stream functions) - 2. Create ArrayFire arrays from existing CUDA pointers - 3. Perform operations on ArrayFire arrays - 4. Instruct ArrayFire to finish operations using [eval][11] and [sync][12] - 5. Obtain pointers to important memory - 6. Continue your CUDA application. - 7. Free non-managed memory - -To create the [Array][14] fom device pointer, you should use one of the following approaches: - -Using DeviceBuffer from [RustaCUDA][10], or a Wrapper Object for CUDA device memory -```rust -let mut buffer = memory::DeviceBuffer::from_slice(&v).unwrap(); - -let array_dptr = Array::new_from_device_ptr( - buffer.as_device_ptr().as_raw_mut(), dim4!(10, 10)); - -array_dptr.lock(); // Needed to avoid free as arrayfire takes ownership -``` - -Using raw pointer returned from cuda\_malloc interface exposed by [RustaCUDA][10] -```rust -let mut dptr: *mut f32 = std::ptr::null_mut(); -unsafe { - dptr = memory::cuda_malloc::(10*10).unwrap().as_raw_mut(); -} - -let array_dptr = Array::new_from_device_ptr(dptr, dim4!(10, 10)); -// After ArrayFire takes over ownership of the pointer, you can use other -// arrayfire functions as usual. -``` - -ArrayFire's memory manager automatically assumes responsibility for any memory provided to it. -Thus ArrayFire could free or reuse the memory at any later time. If this behavior is not desired, -you may call [Array::unlock][13] and manage the memory yourself. However, if you do so, please be -cautious not to free memory when ArrayFire might be using it! - -The seven steps above are best illustrated using a fully-worked example: - -```rust -{{#include ../../cuda-interop/examples/cuda_af_app.rs}} -``` - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.new_from_device_ptr -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.device_ptr -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.lock -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.unlock -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.get_device.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_device.html -[7]: http://arrayfire.org/arrayfire-rust/af_cuda_interop/fn.get_device_native_id.html -[8]: http://arrayfire.org/arrayfire-rust/af_cuda_interop/fn.set_device_native_id.html -[9]: http://arrayfire.org/arrayfire-rust/af_cuda_interop/fn.get_stream.html -[10]: https://github.com/bheisler/RustaCUDA -[11]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.eval -[12]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.sync.html -[13]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.unlock -[14]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html diff --git a/tutorials-book/src/getting_started.md b/tutorials-book/src/getting_started.md deleted file mode 100644 index c9dbad93b..000000000 --- a/tutorials-book/src/getting_started.md +++ /dev/null @@ -1,208 +0,0 @@ -ArrayFire is a high performance software library for parallel computing with an easy-to-use API. -ArrayFire abstracts away much of the details of programming parallel architectures by providing -a high-level container object, the [Array][1], that represents data stored on a CPU, GPU, FPGA, -or other type of accelerator. This abstraction permits developers to write massively parallel -applications in a high-level language where they need not be concerned about low-level optimizations -that are frequently required to achieve high throughput on most parallel architectures. - -## Supported data types - -ArrayFire provides one generic container object, the [Array][1] on which functions and mathematical -operations are performed. The `Array` can represent one of many different [basic data types][2]: - -* [F32][2] real single-precision (`float`) -* [C32][2] complex single-precision (`cfloat`) -* [F64][2] real double-precision (`double`) -* [C64][2] complex double-precision (`cdouble`) -* [B8 ][2] 8-bit boolean values (`bool`) -* [S32][2] 32-bit signed integer (`int`) -* [U32][2] 32-bit unsigned integer (`unsigned`) -* [U8 ][2] 8-bit unsigned values (`unsigned char`) -* [S64][2] 64-bit signed integer (`intl`) -* [U64][2] 64-bit unsigned integer (`uintl`) -* [S16][2] 16-bit signed integer (`short`) -* [U16][2] 16-bit unsigned integer (`unsigned short`) -* [F16][2] 16-bit floating point number ([`half::f16`][3]) - -Most of these data types are supported on all modern GPUs; however, some older devices may lack -support for double precision arrays. In this case, a runtime error will be generated when the array -is constructed. - -If not specified, `Array`s are created as single precision floating point numbers ([F32][2]). - -## Creating and populating an Array - -ArrayFire [Array][1]'s represent memory stored on the device. As such, creation and population of -an array will consume memory on the device which cannot freed until the `array` object goes out of -scope. As device memory allocation can be expensive, ArrayFire also includes a memory manager which -will re-use device memory whenever possible. - -Arrays can be created using one of the [array constructors][4]. Below we show how to create 1D, 2D, -and 3D arrays with uninitialized values: - -```rust,noplaypen -let garbageVals = Array::new_empty(Dim4::new(&[3, 1, 1, 1]), DType::F32); -``` - -However, uninitialized memory is likely not useful in your application. ArrayFire provides several -convenient functions for creating arrays that contain pre-populated values including constants, -uniform random numbers, uniform normally distributed numbers, and the identity matrix: - -```rust,noplaypen -// Create an array filled with constant value of 2.0 of type floating point -// The type of Array is infered from the type of the constant argument -let cnst = constant(2.0f32, Dim4::new(&[5, 5, 1, 1])); -print(&cnst); -``` -```rust,noplaypen -println!("Create a 5-by-3 matrix of random floats on the GPU"); -let dims = Dim4::new(&[5, 3, 1, 1]); -let a = randu::(dims); -print(&a); -``` - -As stated above, the default data type for arrays is [F32][2](32-bit floating point number) unless -specified otherwise. - -ArrayFire `Array`s may also be populated from data found on the host. For example: - -```rust,noplaypen -let values: [u32; 3] = [1u32, 2, 3]; -let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); -print(&indices); -``` - -## Properties of an Array - -ArrayFire provides several functions to determine various aspects of arrays. This includes -functions to print the contents, query dimensions, and determine various other aspects of arrays. - -The [print][5] function can be used to print arrays that have already been generated or any -expression involving arrays: - -```rust,noplaypen -let values: [f32; 3] = [1.0, 2.0, 3.0]; -let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); -print(&indices); -``` - -The dimensions of an array may be determined using either a [Dim4][6] object or by accessing the -dimensions directly using the [Dim4::get][7] and [Dim4::numdims][8] functions: - -```rust,noplaypen -let values: [f32; 3] = [1.0, 2.0, 3.0]; -let dims: Dim4 = Dim4::new(&[3, 1, 1, 1]); -let indices = Array::new(&values, dims); -println!("Dims {:?} with dimensions {}", dims.get(), dims.ndims()); -``` - -In addition to dimensions, arrays also carry several properties including methods to determine the -underlying type and size (in bytes). You can even determine whether the array is empty, real/complex, -a row/column, or a scalar or a vector. For further information on these capabilities, we suggest you -consult the full documentation on the [Array][1]. - -## Writing math expressions using ArrayFire - -ArrayFire features an intelligent Just-In-Time (JIT) compilation engine that converts expressions -using arrays into the smallest number of CUDA/OpenCL kernels. For most operations on Arrays, -ArrayFire functions like a vector library. That means that an element-wise operation, like -`c[i] = a[i] + b[i]` in C, would be written more concisely without indexing, like `c = a + b`. When -there are multiple expressions involving arrays, ArrayFire's JIT engine will merge them together. -This "kernel fusion" technology not only decreases the number of kernel calls, but, more importantly, avoids extraneous global memory operations. - -Our JIT functionality extends across C API boundary and only ends when a non-JIT function is -encountered or a synchronization operation is explicitly called by the code. - -ArrayFire provides hundreds of functions for element-wise operations. All of the standard operators -(e.g. +,-,\*,/) are supported as are most transcendental functions (sin, cos, log, sqrt, etc.). Here are a few examples: - -```rust,noplaypen -let num_rows: u64 = 5; -let num_cols: u64 = 3; -let dims = Dim4::new(&[num_rows, num_cols, 1, 1]); -let a = randu::(dims); -let b = randu::(dims); -print(&a); -print(&b); -let c = a + b; -print(&c); - -//Example of *Assign traits -let mut d = randu::(dims); -let e = constant(1f32, dims); -d += e; -print(&d); -``` - -## Indexing - -Like all functions in ArrayFire, indexing is also executed in parallel on the OpenCL/CUDA device. To -index `Array`s you may use one or a combination of the following functions: - -* [Seq][9] representing a linear sequence -* [Seq::Default()][9] representing the entire dimension -* [row(&Array, i)][10] or [col(&Array, i)][11] specifying a single row/column -* [rows(&Array, first,last)][12] or [cols(&Array, first,last)][13] specifying a span of rows or columns - -Please see the [indexing page](./indexing.md) for several examples of how to use these functions. - -## Access to Array memory on the host - -Memory in `af::Array`s may be accessed using the [Array::host()][14] method. The `host` function -*copies* the data from the device and makes it available in a standard slice or similar container on -the host. As such, it is up to the developer to manage any memory returned by `host`. - - - -## Bitwise operators - -In addition to supporting standard mathematical functions, Arrays that contain integer data types -also support bitwise operators including and, or, and shift etc. Operator traits for Array as well -as separate functions are also defined to support various use cases. - -```rust,noplaypen -let dims = Dim4::new(&[5, 3, 1, 1]); -let a = randu::(dims); -let b = randu::(dims); - -print(&a); -print(&b); - -let c = &a | &b; //Borrowing to avoid move of a and b, a | b is also valid -let d = bitand(&a, &b, false); - -print(&c); -print(&d); -``` - -## Where to go for help? - -* [Google Groups][15] -* ArrayFire Services: [Consulting][16] | [Support][17] | [Training][18] -* [ArrayFire Blogs][19] -* Email: - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/enum.DType.html -[3]: https://crates.io/crates/half -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.new_empty -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.print.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Dim4.html -[7]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Dim4.html#method.get -[8]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Dim4.html#method.ndims -[9]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Seq.html -[10]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.row.html -[11]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.col.html -[12]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.rows.html -[13]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.cols.html -[14]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Dim4.html#method.host -[15]: https://groups.google.com/forum/#!forum/arrayfire-users -[16]: http://arrayfire.com/consulting/ -[17]: http://arrayfire.com/support/ -[18]: http://arrayfire.com/training/ -[19]: http://arrayfire.com/blog/ diff --git a/tutorials-book/src/indexing.md b/tutorials-book/src/indexing.md deleted file mode 100644 index ee0b25668..000000000 --- a/tutorials-book/src/indexing.md +++ /dev/null @@ -1,126 +0,0 @@ -# Indexing - -Indexing in ArrayFire is a powerful but easy to abuse feature. This feature allows you to reference -or copy subsections of a larger array and perform operations on only a subset of elements. - -This chapter is split into the following sections: -- [Index an Array using Seq Objects](#using-seq-objects) - - [Create a view of an existing Array](#create-a-view-of-an-existing-array) - - [Modify a sub region of an existing Array](#modify-a-sub-region-of-an-existing-array) -- [Using Array and Seq combination](#using-array-and-seq-combination) - - [Create a view of an existing Array](#create-a-view-of-an-existing-array) - - [Modify a sub region of an existing Array](#modify-a-sub-region-of-an-existing-array) -- [Extract or Set rows/columns of an Array](#extract-or-set-rowscolumns-of-an-array) -- [Negative Indices](#negative-indices) - -[Indexer][1] structure is the key element used in Rust wrapper of ArrayFire for creating references -to existing Arrays. The above sections illustrate how it can be used in conjunction with `Seq` -and/or `Array`. Apart from that, each section also showcases a macro based equivalent -code(if one exists) that is more terse in syntax but offers the same functionality. - -## Using Seq objects - -### Create a view of an existing Array - -We will Sequences and the function [index][3] in this approach. - -```rust,noplaypen -{{#include ../../src/core/index.rs:non_macro_seq_index}} -``` -However, the same above code can be condensed into a much terse syntax with the help of [view][11] -macro. Take a look at the following two approaches using view macro. -```rust, noplaypen -{{#include ../../src/core/index.rs:seq_index}} -``` -

OR
- -```rust, noplaypen -{{#include ../../src/core/macros.rs:seq_view2}} -``` - -### Modify a sub region of an existing Array - -Let us take a look at an example where a portion of an existing Array will be set to with another -Array. We will an constant value Array and the function [assign\_seq][4] in the below example. - -```rust,noplaypen -{{#include ../../src/core/index.rs:non_macro_seq_assign}} -``` - -A much terser way of doing the same using macro is shown below -```rust,noplaypen -{{#include ../../src/core/macros.rs:macro_seq_assign}} -``` - -> **NOTE** Normally you want to avoid accessing individual elements of the array like this for performance reasons. - -## Using Array and Seq combination - -### Create a view of an existing Array - -To use a combination of Array and Seq objects to index an existing Array, we will need a more -generalized function [index\_gen][12]. - -```rust,noplaypen -{{#include ../../src/core/index.rs:non_macro_seq_array_index}} -``` -Similar to how [view][11] macro helped with abreviating the syntax when indexing with just -sequences, it can also help when using a combination of Seq and Array. -```rust, noplaypen -{{#include ../../src/core/index.rs:seq_array_index}} -``` - -### Modify a sub region of an existing Array - -Set a portion of an existing Array with another Array using a combination of `Seq` and `Array`. -We will use [assign\_gen][13] function to do it. - - ```rust,noplaypen -{{#include ../../src/core/index.rs:non_macro_seq_array_assign}} - ``` -
OR
- - ```rust,noplaypen -{{#include ../../src/core/macros.rs:macro_seq_array_assign}} - ``` - -## Extract or Set rows/columns of an Array - -Extract a specific set of rows/coloumns from an existing Array. - -```rust,noplaypen -{{#include ../../src/core/index.rs:setrow}} -``` - -You can also use [rows][5] & [cols][6] to retrieve a subset of rows or coloumns respectively. - -Similarly, [set\_row][7] & [set\_rows][9] can be used to change the values in a particular set of -rows using another Array. [set\_col][8] & [set\_cols][10] has same functionality, except that it is -for coloumns. - -## Negative Indices - -Negative indices can also be used to refer elements from the end of a given axis. Negative value for -a row/column/slice will fetch corresponding row/column/slice in reverse order. Given below are some -examples that showcase getting row(s)/col(s) from an existing Array. - -```rust,noplaypen -{{#include ../../src/core/index.rs:get_row}} -``` - -```rust,noplaypen -{{#include ../../src/core/index.rs:get_rows}} -``` - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Indexer.html -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.index.html -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.assign_seq.html -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.rows.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.cols.html -[7]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_row.html -[8]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_col.html -[9]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_rows.html -[10]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_cols.html -[11]: http://arrayfire.org/arrayfire-rust/arrayfire/macro.view.html -[12]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.index_gen.html -[13]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.assign_gen.html diff --git a/tutorials-book/src/interop_excerpts.md b/tutorials-book/src/interop_excerpts.md deleted file mode 100644 index 6689522af..000000000 --- a/tutorials-book/src/interop_excerpts.md +++ /dev/null @@ -1,15 +0,0 @@ -Although ArrayFire is quite extensive, there remain many cases in which you may want to write custom -kernels in CUDA or OpenCL. For example, you may wish to add ArrayFire to an existing code base to -increase your productivity, or you may need to supplement ArrayFire's functionality with your own -custom implementation of specific algorithms. - -It is fairly straightforward to interface ArrayFire with your own custom code. ArrayFire provides -several functions to ease this process including: - -Adding ArrayFire to an existing application is slightly more involved and can be somewhat tricky due -to several optimizations we implement. The most important are as follows: - -- ArrayFire assumes control of all memory provided to it. -- ArrayFire does not (in general) support in-place memory transactions. - -We will discuss the implications of these items below. To add ArrayFire to existing code you need to: diff --git a/tutorials-book/src/multi-threading.md b/tutorials-book/src/multi-threading.md deleted file mode 100644 index 534ed047d..000000000 --- a/tutorials-book/src/multi-threading.md +++ /dev/null @@ -1,56 +0,0 @@ -# ArrayFire in Threaded Applications - -In this chapter, we will looking at how to use ArrayFire in multi-threaded programs. We shall -go over the details in the following order. - -- [Move an Array to thread](#move-an-array-to-thread) -- [Read Array from Multiple threads](#read-array-from-multiple-threads) -- [Write to Array from Multiple threads](#write-to-array-from-multiple-threads) -- [Write to single Array using Channel](#write-to-single-array-using-channel) - -## Move an Array to thread - -In this section, we are going to create an Array on main thread and move it to a child thread, -modify it and then print it from the child thread. - -```rust,noplaypen -{{#include ../../src/core/array.rs:move_array_to_thread}} -``` - -## Read Array from Multiple threads - -Now, let's expand the earlier example to do a bunch of arithmetic operations in parallel on -multiple threads using the same Array objects. - -```rust,noplaypen -{{#include ../../src/core/array.rs:read_from_multiple_threads}} -``` - -Given below is the definition of the enum `Op` we used in the example for illustration simplicity. -```rust,noplaypen -{{#include ../../src/core/array.rs:multiple_threads_enum_def}} -``` - -## Write to Array from Multiple threads - -Let us further expand the earlier example by accumulating the results of the arithmetic operations -into a single Array object. - -The code will differ from earlier section in couple of locations: - -- In the main thread, we wrap the accumulating Array in a read-write lock (`std::sync::RwLock`) - which is in turn wrapped in an atomically reference counted counter a.k.a `std::sync::Arc`. -- In the children threads, we use the guarded objects returned by RwLock's write method to access - the accumulator Array. - -```rust,noplaypen -{{#include ../../src/core/array.rs:access_using_rwlock}} -``` - -## Write to single Array using Channel - -In this section, we shall modify the example to use channel instead of data sharing. - -```rust,noplaypen -{{#include ../../src/core/array.rs:accum_using_channel}} -``` diff --git a/tutorials-book/src/opencl-interop.md b/tutorials-book/src/opencl-interop.md deleted file mode 100644 index e51148e33..000000000 --- a/tutorials-book/src/opencl-interop.md +++ /dev/null @@ -1,128 +0,0 @@ -# Interoperability with OpenCL - -{{#include interop_excerpts.md:1:4}} - -ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. As such, most -of the interoperability functions focus on reducing potential synchronization conflicts between -ArrayFire and OpenCL. - -## Basics - -{{#include interop_excerpts.md:6:7}} - -| Function | Purpose | -|------------------------------------|-----------------------------------------------------------| -| [Array::new\_from\_device\_ptr][1] | Construct an ArrayFire Array from cl\_mem | -| [Array::device\_ptr][2] | Obtain a pointer to the device memory (implies `lock`) | -| [Array::lock][3] | Removes ArrayFire's control of a device memory pointer | -| [Array::unlock][4] | Restores ArrayFire's control over a device memory pointer | -| [get\_platform][7] | Get ArrayFire's current cl\_platform | -| [get\_device][5] | Gets the current ArrayFire device ID | -| [get\_device\_id][8] | Get ArrayFire's current cl\_device\_id | -| [set\_device\_id][9] | Set ArrayFire's device from a cl\_device\_id | -| [set\_device][6] | Switches ArrayFire to the specified device | -| [get\_context][10] | Get ArrayFire's current cl\_context | -| [get\_queue][11] | Get ArrayFire's current cl\_command\_queue | -| [get\_device\_type][12] | Get the current [DeviceType][16] | - -Note that the pointer returned by [Array::device\_ptr][2] should be cast to `cl_mem` before using -it with OpenCL opaque types. The pointer is a `cl_mem` internally that is force casted to pointer -type by ArrayFire before returning the value to caller. - -Additionally, the OpenCL backend permits the programmer to add and remove custom devices from the -ArrayFire device manager. These permit you to attach ArrayFire directly to the OpenCL queue used by -other portions of your application. - -| Function | Purpose | -|-------------------------------|----------------------------------------------------------| -| [add\_device\_context][13] | Add a new device to ArrayFire's device manager | -| [set\_device\_context][15] | Set ArrayFire's device from cl\_device\_id & cl\_context | -| [delete\_device\_context][14] | Remove a device from ArrayFire's device manager | - -Below we provide two worked examples on how ArrayFire can be integrated -into new and existing projects. - -## Adding custom OpenCL kernels to an existing ArrayFire application - -By default, ArrayFire manages its own context, queue, memory, and creates custom IDs for devices. -Thus there is some bookkeeping that needs to be done to integrate your custom OpenCL kernel. - -If your kernels can share operate in the same queue as ArrayFire, you should: - -1. Obtain the OpenCL context, device, and queue used by ArrayFire -2. Obtain cl\_mem references to [Array][18] objects -3. Load, build, and use your kernels -4. Return control of [Array][18] memory to ArrayFire - -Note, ArrayFire uses an in-order queue, thus when ArrayFire and your kernels are operating in the -same queue, there is no need to perform any synchronization operations. - -This process is best illustrated with a fully worked example: - -```rust -{{#include ../../opencl-interop/examples/custom_kernel.rs}} -``` - -If your kernels needs to operate in their own OpenCL queue, the process is essentially identical, -except you need to instruct ArrayFire to complete its computations using the [sync][17] function -prior to launching your own kernel and ensure your kernels are complete using `clFinish` -(or similar) commands prior to returning control of the memory to ArrayFire: - -1. Obtain the OpenCL context, device, and queue used by ArrayFire -2. Obtain cl\_mem references to [Array][18] objects -3. Instruct ArrayFire to finish operations using [sync][17] -4. Load, build, and use your kernels -5. Instruct OpenCL to finish operations using clFinish() or similar commands. -6. Return control of [Array][18] memory to ArrayFire - -## Adding ArrayFire to an existing OpenCL application - -{{#include interop_excerpts.md:9:15}} - -1. Instruct OpenCL to complete its operations using clFinish (or similar) -2. Instruct ArrayFire to use the user-created OpenCL Context -3. Create ArrayFire arrays from OpenCL memory objects -4. Perform ArrayFire operations on the [Array][18]s -5. Instruct ArrayFire to finish operations using [sync][17] -6. Obtain cl\_mem references for important memory -7. Continue your OpenCL application - - - -> ArrayFire's memory manager automatically assumes responsibility for any memory provided to -it. If you are creating an array from another RAII style object, you should retain it to ensure -your memory is not deallocated if your RAII object were to go out of scope. - -> If you do not wish for ArrayFire to manage your memory, you may call the [Array::unlock][4] -function and manage the memory yourself; however, if you do so, please be cautious not to call -`clReleaseMemObj` on a `cl_mem` when ArrayFire might be using it! - -Given below is a fully working example: - -```rust -{{#include ../../opencl-interop/examples/ocl_af_app.rs}} -``` - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.new_from_device_ptr -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.device_ptr -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.lock -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.unlock -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.get_device.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_device.html -[7]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.get_platform.html -[8]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.get_device_id.html -[9]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.set_device_id.html -[10]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.get_context.html -[11]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.get_queue.html -[12]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.get_device_type.html -[13]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.add_device_context.html -[14]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.delete_device_context.html -[15]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/fn.set_device_context.html -[16]: http://arrayfire.org/arrayfire-rust/af_opencl_interop/enum.DeviceType.html -[17]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.sync.html -[18]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html diff --git a/tutorials-book/src/serde.md b/tutorials-book/src/serde.md deleted file mode 100644 index c4c5a297a..000000000 --- a/tutorials-book/src/serde.md +++ /dev/null @@ -1,29 +0,0 @@ -# Serialization & Deserialization of ArrayFire Objects - -To save [Array][1] contents, shape in JSON format, it just takes couple of lines of code as shown below: -```rust,noplaypen -{{#include ../../src/core/array.rs:array_json_serde_snippet}} -``` -Saving [Array][1] in different formats is as simple as changing the object qualifier of methods `serialize` and `deserialize`. For example, if user wants to store [Array][1] in `bincode` format instead of JSON, the above code only needs to be change in couple of lines. -```rust,noplaypen -{{#include ../../src/core/array.rs:array_bincode_serde_snippet}} -``` - -In similar fashion, we can serialize and deserialize [Dim4][2], [RandomEngine][3], [Seq][4] and other Enums. Examples of [Dim4][2], [RandomEngine][3] and [Seq][4] are given below. - -```rust,noplaypen -{{#include ../../src/core/dim4.rs:dim4_json_serde_snippet}} -``` - -```rust,noplaypen -{{#include ../../src/core/random.rs:rng_bincode_serde_snippet}} -``` - -```rust,noplaypen -{{#include ../../src/core/seq.rs:seq_json_serde_snippet}} -``` - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Dim4.html -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.RandomEngine.html -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Seq.html diff --git a/tutorials-book/src/vectorization.md b/tutorials-book/src/vectorization.md deleted file mode 100644 index 13d485d47..000000000 --- a/tutorials-book/src/vectorization.md +++ /dev/null @@ -1,99 +0,0 @@ -# Vectorization - -Programmers and Data Scientists want to take advantage of fast and parallel computational devices. -Writing vectorized code is necessary to get the best performance out of the current generation -parallel hardware and scientific computing software. However, writing vectorized code may not be -immediately intuitive. ArrayFire provides many ways to vectorize a given code segment. In this -chapter, we present several methods to vectorize code using ArrayFire and discuss the benefits and -drawbacks associated with each method. - -## Generic/Default vectorization -By its very nature, ArrayFire is a vectorized library. Most functions operate on Arrays as a whole -i.e. on all elements in parallel. For example consider the following code: - -```rust,noplaypen -let mut a = af::range(Dim::new(&[10, 1, 1, 1])); // [0, 9] -a = a + 1; // [1, 10] -``` - -This code will result in a single kernel that operates on all 10 elements of `a` in parallel. - -A small subset of such vectorized ArrayFire functions are given below for quick reference: - -| Operator Category | Functions | -|----------------------------------|------------------------------------------------------------| -| Arithmetic operations | +, -, \*, /, %, >>, << | -| Logical operations | &&, \|\|, <, >, ==, != etc. | -| Numeric functions | [abs][1], [floor][2], [round][3], [min][4], [max][5], etc. | -| Complex operations | [real][6], [imag][7], [conjg][8], etc. | -| Exponential and logarithmic fns | [exp][9], [log][10], [expm1][11], [log1p][12], etc. | -| Trigonometric functions | [sin][13], [cos][14], [tan][15], etc. | -| Hyperbolic functions | [sinh][16], [cosh][17], [tanh][18], etc. | - -In addition to element-wise operations, many other functions are also vectorized in ArrayFire. - -Notice that even functions that perform some form of aggregation (e.g. [sum][19] or [min][14]), -signal processing (like [convolve][20]), and image processing functions (i.e. [rotate][21] etc.) -- all support vectorization on different columns or images. - -For example, if we have `NUM` images of size `WIDTH`x`HEIGHT`, one could convolve each image in a -vector fashion as follows: - -```rust,noplaypen -let g_coef: [f32, 9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; - -let f = Array::new(g_coef, Dim4::new(&[3, 3, 1, 1])); -let filter = f * 1.0f32/16; - -let signal = randu(WIDTH, HEIGHT, NUM); -let conv = convolve2(signal, filter, ConvMode::DEFAULT, ConvDomain::AUTO); -``` - -Similarly, one can rotate 100 images by 45 degrees in a single call using code like the following: - -```rust,noplaypen -// Construct an array of 100 WIDTH x HEIGHT images of random numbers -let imgs = randu(WIDTH, HEIGHT, 100); - -// Rotate all of the images in a single command -let rot_imgs = rotate(imgs, 45.0, False, InterpType::LINEAR); -``` - -Although *most* functions in ArrayFire do support vectorization, some do not. Most notably, all -linear algebra functions. Even though they are not vectorized linear algebra operations, they still -execute in parallel on your hardware. - -Using the built in vectorized operations should be the first and preferred method of vectorizing any -code written with ArrayFire. - -## GFOR - -This construct is similar to gfor loop from C++ API of ArrayFire. It has not been implemented in -rust wrapper. This section will be updated once the feature has been added to the crate. - -## batch\_func - -This another pending feature that is similar to our C++ API of [batchFunc()][22] - -[1]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.abs.html -[2]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.floor.html -[3]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.round.html -[4]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.min.html -[5]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.max.html -[6]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.real.html -[7]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.imag.html -[8]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.conjg.html -[9]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.exp.html -[10]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.log.html -[11]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.expm1.html -[12]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.log1p.html -[13]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.sin.html -[14]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.cos.html -[15]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.tan.html -[16]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.sinh.html -[17]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.cosh.html -[18]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.tanh.html -[19]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.sum.html -[20]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.convolve1.html -[21]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.rotate.html -[22]: http://arrayfire.org/docs/namespaceaf.htm#aa0eb9e160f5be4b95234543e5c47934b diff --git a/wheel.svg b/wheel.svg new file mode 100644 index 000000000..01da3b24c --- /dev/null +++ b/wheel.svg @@ -0,0 +1 @@ + \ No newline at end of file