diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index a55a2bd6b..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,127 +0,0 @@ -### v3.3.20160624 -- Adding 16 bit integer support -- Adding support for sphinx documentation - -### v3.3.20160516 -- Bugfix: Increase arrayfire's priority over numpy for mixed operations - -- Added new library functions - - `get_backend` returns backend name - -### v3.3.20160510 -- Bugfix to `af.histogram` - -- Added missing functions / methods - - `gaussian_kernel` - -- Added new array properties - - `Array.T` now returns transpose - - `Array.H` now returns hermitian transpose - - `Array.shape` now allows easier access individual dimensions - -### v3.3.20160427 -- Fixes to numpy interop on Windows -- Fixes issues with occasional double free -- Fixes to graphics examples - -### v3.3.20160328 -- Fixes to make arrayfire-python to work on 32 bit systems - -### v3.3.20160320 -- Feature parity with Arrayfire 3.3 libs - - Functions to interact with arryafire's internal data structures. - - `Array.offset` - - `Array.strides` - - `Array.is_owner` - - `Array.is_linear` - - `Array.raw_ptr` - - Array constructor now takes `offset` and `strides` as optional parameters. - - New visualization functions: `scatter` and `scatter3` - - OpenCL backend specific functions: - - `get_device_type` - - `get_platform` - - `add_device_context` - - `delete_device_context` - - `set_device_context` - - Functions to allocate and free memory on host and device - - `alloc_host` and `free_host` - - `alloc_pinned` and `free_pinned` - - `alloc_device` and `free_device` - - Function to query which device and backend an array was created on - - `get_device_id` - - `get_backend_id` - - Miscellaneous functions - - `is_lapack_available` - - `is_image_io_available` - -- Interopability - - Transfer PyCUDA GPUArrays using `af.pycuda_to_af_array` - - Transfer PyOpenCL Arrays using `af.pyopencl_to_af_array` - - New helper function `af.to_array` added to convert a different `array` to arrayfire Array. - - This function can be used in place of `af.xyz_to_af_array` functions mentioned above. - -- Deprecated functions list - - `lock_device_ptr` is deprecated. Use `lock_array` instead. - - `unlock_device_ptr` is deprecated. Use `unlock_array` instead. - -- Bug Fixes: - - [Boolean indexing giving faulty results](https://github.com/arrayfire/arrayfire-python/issues/68) for multi dimensional arrays. - - [Enum types comparision failures](https://github.com/arrayfire/arrayfire-python/issues/65) in Python 2.x - - [Support loading SO versioned libraries](https://github.com/arrayfire/arrayfire-python/issues/64) in Linux and OSX. - - Fixed typo that prevented changing backend - - Fixed image processing functions that accepted floating point scalar paramters. - - Affected functions include: `translate`, `scale`, `skew`, `histogram`, `bilateral`, `mean_shift`. -### v3.2.20151224 -- Bug fixes: - - A default `AF_PATH` is set if none is found as an environment variable. - -- Examples: - - Heston model example uses a smaller data set to help run on low end GPUs. - -### v3.2.20151214 -- Bug fixes: - - `get_version()` now returns ints instead of `c_int` - - Fixed bug in `tests/simple/device.py` - -- The module now looks at additional paths when loading ArrayFire libraries. - - Link to the wiki is provided when `ctypes.cdll.LoadLibrary` fails. - -- New function: - - `info_str()` returns information similar to `info()` as a string. - -- Updated README.md with latest instructions - -### v3.2.20151211 -- Feature parity with ArrayFire 3.2 libs - - New computer vision functions: `sift`, `gloh`, `homography` - - New graphics functions: `plot3`, `surface` - - Functions to load and save native images: `load_image_native`, `save_image_native` - - Use `unified` backend when possible - -- Added missing functions - - `eval`, `init`, `convolve2_separable`, `as_type` method - - `cuda` backend specific functions - - `opencl` backend specific functions - - `timeit` function to benchmark arrayfire functions - -- Added new examples - - getting_started: `intro`, `convolve` - - benchmarks: `bench_blas`, `bench_fft` - - financial: `monte_carlo_options`, `black_scholes`, `heston_model` - - graphics: `fractal`, `histogram`, `plot3d`, `conway`, `surface` - -- Bug fixes - - Fixed bug when array types were being reported incorrectly - - Fixed various bugs in graphics functions - -### v3.1.20151111 -- Feature parity with ArrayFire 3.1 libs -- Ability to interop with other python libs -- Ability to extract raw device pointers -- Load and Save arrays from disk -- Improved `__repr__` support - -### v3.0.20150914 -- Feature parity with ArrayFire 3.0 libs -- Ability to switch all backends -- Supports both python2 and python3 diff --git a/README.md b/README.md deleted file mode 100644 index be1c4eb51..000000000 --- a/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# ArrayFire Python Bindings - -[ArrayFire](https://github.com/arrayfire/arrayfire) 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 Python bindings for the ArrayFire library. - -## Status -| OS | Tests | -|:-------:|:-------:| -| Linux | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/python-linux)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/python-linux/) | -| Windows | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/python-windows)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/python-windows/) | -| OSX | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/python-osx)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/python-osx/) | - -## Example - -```python -import arrayfire as af - -# Display backend information -af.info() - -# Generate a uniform random array with a size of 5 elements -a = af.randu(5, 1) - -# Print a and its minimum value -af.display(a) - -# Print min and max values of a -print("Minimum, Maximum: ", af.min(a), af.max(a)) -``` - -## Sample outputs - -On an AMD GPU: - -``` -Using opencl backend -ArrayFire v3.0.1 (OpenCL, 64-bit Linux, build 17db1c9) -[0] AMD : Spectre --1- AMD : AMD A10-7850K Radeon R7, 12 Compute Cores 4C+8G - -[5 1 1 1] -0.4107 -0.8224 -0.9518 -0.1794 -0.4198 - -Minimum, Maximum: 0.17936542630195618 0.9517996311187744 -``` - -On an NVIDIA GPU: - -``` -Using cuda backend -ArrayFire v3.0.0 (CUDA, 64-bit Linux, build 86426db) -Platform: CUDA Toolkit 7, Driver: 346.46 -[0] Tesla K40c, 12288 MB, CUDA Compute 3.5 --1- GeForce GTX 750, 1024 MB, CUDA Compute 5.0 - -Generate a random matrix a: -[5 1 1 1] -0.7402 -0.9210 -0.0390 -0.9690 -0.9251 - -Minimum, Maximum: 0.039020489901304245 0.9689629077911377 -``` - -Fallback to CPU when CUDA and OpenCL are not availabe: - -``` -Using cpu backend -ArrayFire v3.0.0 (CPU, 64-bit Linux, build 86426db) - -Generate a random matrix a: -[5 1 1 1] -0.0000 -0.1315 -0.7556 -0.4587 -0.5328 - -Minimum, Maximum: 7.825903594493866e-06 0.7556053400039673 -``` - -Choosing a particular backend can be done using `af.backend.set( backend_name )` where backend_name can be one of: "_cuda_", "_opencl_", or "_cpu_". The default device is chosen in the same order of preference. - -## Requirements - -Currently, this project is tested only on Linux and OSX. You also need to have the ArrayFire C/C++ library installed on your machine. You can get it from the following sources. - -- [Download and install binaries](https://arrayfire.com/download) -- [Build and install from source](https://github.com/arrayfire/arrayfire) - -Please check the following links for dependencies. - -- [Linux dependencies](http://www.arrayfire.com/docs/using_on_linux.htm) -- [OSX dependencies](http://www.arrayfire.com/docs/using_on_osx.htm) - -## Getting started - -**Install the last stable version:** - -``` -pip install arrayfire -``` - -**Install the development version:** - -``` -pip install git+git://github.com/arrayfire/arrayfire.git@devel -``` - -**Installing offline** - -``` -cd path/to/arrayfire-python -python setup.py install -``` - -**Post Installation** - -Please follow [these instructions](https://github.com/arrayfire/arrayfire-python/wiki) to ensure the arrayfire-python can find the arrayfire libraries. - -## Acknowledgements - -The ArrayFire library is written by developers at [ArrayFire](http://arrayfire.com) LLC -with [contributions from several individuals](https://github.com/arrayfire/arrayfire_python/graphs/contributors). - -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. diff --git a/__af_version__.py b/__af_version__.py deleted file mode 100644 index 72e423a40..000000000 --- a/__af_version__.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/python - -####################################################### -# Copyright (c) 2015, ArrayFire -# All rights reserved. -# -# This file is distributed under 3-clause BSD license. -# The complete license agreement can be obtained at: -# http://arrayfire.com/licenses/BSD-3-Clause -######################################################## - -version = "3.3" -release = "20160624" -full_version = version + "." + release diff --git a/_modules/arrayfire/algorithm.html b/_modules/arrayfire/algorithm.html new file mode 100644 index 000000000..9deaa813e --- /dev/null +++ b/_modules/arrayfire/algorithm.html @@ -0,0 +1,861 @@ + + + + + + + + arrayfire.algorithm — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.algorithm

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Vector algorithms (sum, min, sort, etc).
+"""
+
+from .library import *
+from .array import *
+
+def _parallel_dim(a, dim, c_func):
+    out = Array()
+    safe_call(c_func(c_pointer(out.arr), a.arr, c_int_t(dim)))
+    return out
+
+def _reduce_all(a, c_func):
+    real = c_double_t(0)
+    imag = c_double_t(0)
+
+    safe_call(c_func(c_pointer(real), c_pointer(imag), a.arr))
+
+    real = real.value
+    imag = imag.value
+    return real if imag == 0 else real + imag * 1j
+
+def _nan_parallel_dim(a, dim, c_func, nan_val):
+    out = Array()
+    safe_call(c_func(c_pointer(out.arr), a.arr, c_int_t(dim), c_double_t(nan_val)))
+    return out
+
+def _nan_reduce_all(a, c_func, nan_val):
+    real = c_double_t(0)
+    imag = c_double_t(0)
+
+    safe_call(c_func(c_pointer(real), c_pointer(imag), a.arr, c_double_t(nan_val)))
+
+    real = real.value
+    imag = imag.value
+    return real if imag == 0 else real + imag * 1j
+
+def _FNSD(dim, dims):
+    if dim >= 0:
+        return int(dim)
+
+    fnsd = 0
+    for i, d in enumerate(dims):
+        if d > 1:
+            fnsd = i
+            break
+    return int(fnsd)
+
+def _rbk_dim(keys, vals, dim, c_func):
+    keys_out = Array()
+    vals_out = Array()
+    rdim = _FNSD(dim, vals.dims())
+    safe_call(c_func(c_pointer(keys_out.arr), c_pointer(vals_out.arr), keys.arr, vals.arr, c_int_t(rdim)))
+    return keys_out, vals_out
+
+def _nan_rbk_dim(a, dim, c_func, nan_val):
+    keys_out = Array()
+    vals_out = Array()
+    rdim = _FNSD(dim, vals.dims())
+    safe_call(c_func(c_pointer(keys_out.arr), c_pointer(vals_out.arr), keys.arr, vals.arr, c_int_t(rdim), c_double_t(nan_val)))
+    return keys_out, vals_out
+
+
[docs]def sum(a, dim=None, nan_val=None): + """ + Calculate the sum of all the elements along a specified dimension. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the sum is required. + nan_val: optional: scalar. default: None + The value that replaces NaN in the array + + Returns + ------- + out: af.Array or scalar number + The sum of all elements in `a` along dimension `dim`. + If `dim` is `None`, sum of the entire Array is returned. + """ + if (nan_val is not None): + if dim is not None: + return _nan_parallel_dim(a, dim, backend.get().af_sum_nan, nan_val) + else: + return _nan_reduce_all(a, backend.get().af_sum_nan_all, nan_val) + else: + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_sum) + else: + return _reduce_all(a, backend.get().af_sum_all)
+ + +
[docs]def sumByKey(keys, vals, dim=-1, nan_val=None): + """ + Calculate the sum of elements along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the sum will occur. + nan_val: optional: scalar. default: None + The value that replaces NaN in the array + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of all elements in `vals` along dimension `dim`. + values: af.Array or scalar number + The sum of all elements in `vals` along dimension `dim` according to keys + """ + if (nan_val is not None): + return _nan_rbk_dim(keys, vals, dim, backend.get().af_sum_by_key_nan, nan_val) + else: + return _rbk_dim(keys, vals, dim, backend.get().af_sum_by_key)
+ +
[docs]def product(a, dim=None, nan_val=None): + """ + Calculate the product of all the elements along a specified dimension. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the product is required. + nan_val: optional: scalar. default: None + The value that replaces NaN in the array + + Returns + ------- + out: af.Array or scalar number + The product of all elements in `a` along dimension `dim`. + If `dim` is `None`, product of the entire Array is returned. + """ + if (nan_val is not None): + if dim is not None: + return _nan_parallel_dim(a, dim, backend.get().af_product_nan, nan_val) + else: + return _nan_reduce_all(a, backend.get().af_product_nan_all, nan_val) + else: + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_product) + else: + return _reduce_all(a, backend.get().af_product_all)
+ +
[docs]def productByKey(keys, vals, dim=-1, nan_val=None): + """ + Calculate the product of elements along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the product will occur. + nan_val: optional: scalar. default: None + The value that replaces NaN in the array + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of all elements in `vals` along dimension `dim`. + values: af.Array or scalar number + The product of all elements in `vals` along dimension `dim` according to keys + """ + if (nan_val is not None): + return _nan_rbk_dim(keys, vals, dim, backend.get().af_product_by_key_nan, nan_val) + else: + return _rbk_dim(keys, vals, dim, backend.get().af_product_by_key)
+ +
[docs]def min(a, dim=None): + """ + Find the minimum value of all the elements along a specified dimension. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the minimum value is required. + + Returns + ------- + out: af.Array or scalar number + The minimum value of all elements in `a` along dimension `dim`. + If `dim` is `None`, minimum value of the entire Array is returned. + """ + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_min) + else: + return _reduce_all(a, backend.get().af_min_all)
+ +
[docs]def minByKey(keys, vals, dim=-1): + """ + Calculate the min of elements along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the min will occur. + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of all elements in `vals` along dimension `dim`. + values: af.Array or scalar number + The min of all elements in `vals` along dimension `dim` according to keys + """ + return _rbk_dim(keys, vals, dim, backend.get().af_min_by_key)
+ +
[docs]def max(a, dim=None): + """ + Find the maximum value of all the elements along a specified dimension. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the maximum value is required. + + Returns + ------- + out: af.Array or scalar number + The maximum value of all elements in `a` along dimension `dim`. + If `dim` is `None`, maximum value of the entire Array is returned. + """ + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_max) + else: + return _reduce_all(a, backend.get().af_max_all)
+ +
[docs]def maxByKey(keys, vals, dim=-1): + """ + Calculate the max of elements along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the max will occur. + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of all elements in `vals` along dimension `dim`. + values: af.Array or scalar number + The max of all elements in `vals` along dimension `dim` according to keys. + """ + return _rbk_dim(keys, vals, dim, backend.get().af_max_by_key)
+ +
[docs]def all_true(a, dim=None): + """ + Check if all the elements along a specified dimension are true. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the product is required. + + Returns + ------- + out: af.Array or scalar number + Af.array containing True if all elements in `a` along the dimension are True. + If `dim` is `None`, output is True if `a` does not have any zeros, else False. + """ + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_all_true) + else: + return _reduce_all(a, backend.get().af_all_true_all)
+ +
[docs]def allTrueByKey(keys, vals, dim=-1): + """ + Calculate if all elements are true along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the all true check will occur. + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of all true check in `vals` along dimension `dim`. + values: af.Array or scalar number + Booleans denoting if all elements are true in `vals` along dimension `dim` according to keys + """ + return _rbk_dim(keys, vals, dim, backend.get().af_all_true_by_key)
+ +
[docs]def any_true(a, dim=None): + """ + Check if any the elements along a specified dimension are true. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the product is required. + + Returns + ------- + out: af.Array or scalar number + Af.array containing True if any elements in `a` along the dimension are True. + If `dim` is `None`, output is True if `a` does not have any zeros, else False. + """ + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_any_true) + else: + return _reduce_all(a, backend.get().af_any_true_all)
+ +
[docs]def anyTrueByKey(keys, vals, dim=-1): + """ + Calculate if any elements are true along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which the any true check will occur. + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of any true check in `vals` along dimension `dim`. + values: af.Array or scalar number + Booleans denoting if any elements are true in `vals` along dimension `dim` according to keys. + """ + return _rbk_dim(keys, vals, dim, backend.get().af_any_true_by_key)
+ +
[docs]def count(a, dim=None): + """ + Count the number of non zero elements in an array along a specified dimension. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the the non zero elements are to be counted. + + Returns + ------- + out: af.Array or scalar number + The count of non zero elements in `a` along `dim`. + If `dim` is `None`, the total number of non zero elements in `a`. + """ + if dim is not None: + return _parallel_dim(a, dim, backend.get().af_count) + else: + return _reduce_all(a, backend.get().af_count_all)
+ +
[docs]def countByKey(keys, vals, dim=-1): + """ + Counts non-zero elements along a specified dimension according to a key. + + Parameters + ---------- + keys : af.Array + One dimensional arrayfire array with reduction keys. + vals : af.Array + Multi dimensional arrayfire array that will be reduced. + dim: optional: int. default: -1 + Dimension along which to count elements. + + Returns + ------- + keys: af.Array or scalar number + The reduced keys of count in `vals` along dimension `dim`. + values: af.Array or scalar number + Count of non-zero elements in `vals` along dimension `dim` according to keys. + """ + return _rbk_dim(keys, vals, dim, backend.get().af_count_by_key)
+ +
[docs]def imin(a, dim=None): + """ + Find the value and location of the minimum value along a specified dimension + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the minimum value is required. + + Returns + ------- + (val, idx): tuple of af.Array or scalars + `val` contains the minimum value of `a` along `dim`. + `idx` contains the location of where `val` occurs in `a` along `dim`. + If `dim` is `None`, `val` and `idx` value and location of global minimum. + """ + if dim is not None: + out = Array() + idx = Array() + safe_call(backend.get().af_imin(c_pointer(out.arr), c_pointer(idx.arr), a.arr, c_int_t(dim))) + return out,idx + else: + real = c_double_t(0) + imag = c_double_t(0) + idx = c_uint_t(0) + safe_call(backend.get().af_imin_all(c_pointer(real), c_pointer(imag), c_pointer(idx), a.arr)) + real = real.value + imag = imag.value + val = real if imag == 0 else real + imag * 1j + return val,idx.value
+ +
[docs]def imax(a, dim=None): + """ + Find the value and location of the maximum value along a specified dimension + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: None + Dimension along which the maximum value is required. + + Returns + ------- + (val, idx): tuple of af.Array or scalars + `val` contains the maximum value of `a` along `dim`. + `idx` contains the location of where `val` occurs in `a` along `dim`. + If `dim` is `None`, `val` and `idx` value and location of global maximum. + """ + if dim is not None: + out = Array() + idx = Array() + safe_call(backend.get().af_imax(c_pointer(out.arr), c_pointer(idx.arr), a.arr, c_int_t(dim))) + return out,idx + else: + real = c_double_t(0) + imag = c_double_t(0) + idx = c_uint_t(0) + safe_call(backend.get().af_imax_all(c_pointer(real), c_pointer(imag), c_pointer(idx), a.arr)) + real = real.value + imag = imag.value + val = real if imag == 0 else real + imag * 1j + return val,idx.value
+ + +
[docs]def accum(a, dim=0): + """ + Cumulative sum of an array along a specified dimension + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: 0 + Dimension along which the cumulative sum is required. + + Returns + ------- + out: af.Array + array of same size as `a` containing the cumulative sum along `dim`. + """ + return _parallel_dim(a, dim, backend.get().af_accum)
+ +
[docs]def scan(a, dim=0, op=BINARYOP.ADD, inclusive_scan=True): + """ + Generalized scan of an array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + dim : optional: int. default: 0 + Dimension along which the scan is performed. + + op : optional: af.BINARYOP. default: af.BINARYOP.ADD. + Binary option the scan algorithm uses. Can be one of: + - af.BINARYOP.ADD + - af.BINARYOP.MUL + - af.BINARYOP.MIN + - af.BINARYOP.MAX + + inclusive_scan: optional: bool. default: True + Specifies if the scan is inclusive + + Returns + --------- + out : af.Array + - will contain scan of input. + """ + out = Array() + safe_call(backend.get().af_scan(c_pointer(out.arr), a.arr, dim, op.value, inclusive_scan)) + return out
+ +
[docs]def scan_by_key(key, a, dim=0, op=BINARYOP.ADD, inclusive_scan=True): + """ + Generalized scan by key of an array. + + Parameters + ---------- + key : af.Array + key array. + + a : af.Array + Multi dimensional arrayfire array. + + dim : optional: int. default: 0 + Dimension along which the scan is performed. + + op : optional: af.BINARYOP. default: af.BINARYOP.ADD. + Binary option the scan algorithm uses. Can be one of: + - af.BINARYOP.ADD + - af.BINARYOP.MUL + - af.BINARYOP.MIN + - af.BINARYOP.MAX + + inclusive_scan: optional: bool. default: True + Specifies if the scan is inclusive + + Returns + --------- + out : af.Array + - will contain scan of input. + """ + out = Array() + safe_call(backend.get().af_scan_by_key(c_pointer(out.arr), key.arr, a.arr, dim, op.value, inclusive_scan)) + return out
+ +
[docs]def where(a): + """ + Find the indices of non zero elements + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + ------- + idx: af.Array + Linear indices for non zero elements. + """ + out = Array() + safe_call(backend.get().af_where(c_pointer(out.arr), a.arr)) + return out
+ +
[docs]def diff1(a, dim=0): + """ + Find the first order differences along specified dimensions + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: 0 + Dimension along which the differences are required. + + Returns + ------- + out: af.Array + Array whose length along `dim` is 1 less than that of `a`. + """ + return _parallel_dim(a, dim, backend.get().af_diff1)
+ +
[docs]def diff2(a, dim=0): + """ + Find the second order differences along specified dimensions + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: 0 + Dimension along which the differences are required. + + Returns + ------- + out: af.Array + Array whose length along `dim` is 2 less than that of `a`. + """ + return _parallel_dim(a, dim, backend.get().af_diff2)
+ +
[docs]def sort(a, dim=0, is_ascending=True): + """ + Sort the array along a specified dimension + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: 0 + Dimension along which sort is to be performed. + is_ascending: optional: bool. default: True + Specifies the direction of the sort + + Returns + ------- + out: af.Array + array containing the sorted values + + Note + ------- + Currently `dim` is only supported for 0. + """ + out = Array() + safe_call(backend.get().af_sort(c_pointer(out.arr), a.arr, c_uint_t(dim), c_bool_t(is_ascending))) + return out
+ +
[docs]def sort_index(a, dim=0, is_ascending=True): + """ + Sort the array along a specified dimension and get the indices. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dim: optional: int. default: 0 + Dimension along which sort is to be performed. + is_ascending: optional: bool. default: True + Specifies the direction of the sort + + Returns + ------- + (val, idx): tuple of af.Array + `val` is an af.Array containing the sorted values. + `idx` is an af.Array containing the original indices of `val` in `a`. + + Note + ------- + Currently `dim` is only supported for 0. + """ + out = Array() + idx = Array() + safe_call(backend.get().af_sort_index(c_pointer(out.arr), c_pointer(idx.arr), a.arr, + c_uint_t(dim), c_bool_t(is_ascending))) + return out,idx
+ +
[docs]def sort_by_key(ik, iv, dim=0, is_ascending=True): + """ + Sort an array based on specified keys + + Parameters + ---------- + ik : af.Array + An Array containing the keys + iv : af.Array + An Array containing the values + dim: optional: int. default: 0 + Dimension along which sort is to be performed. + is_ascending: optional: bool. default: True + Specifies the direction of the sort + + Returns + ------- + (ok, ov): tuple of af.Array + `ok` contains the values from `ik` in sorted order + `ov` contains the values from `iv` after sorting them based on `ik` + + Note + ------- + Currently `dim` is only supported for 0. + """ + ov = Array() + ok = Array() + safe_call(backend.get().af_sort_by_key(c_pointer(ok.arr), c_pointer(ov.arr), + ik.arr, iv.arr, c_uint_t(dim), c_bool_t(is_ascending))) + return ov,ok
+ +
[docs]def set_unique(a, is_sorted=False): + """ + Find the unique elements of an array. + + Parameters + ---------- + a : af.Array + A 1D arrayfire array. + is_sorted: optional: bool. default: False + Specifies if the input is pre-sorted. + + Returns + ------- + out: af.Array + an array containing the unique values from `a` + """ + out = Array() + safe_call(backend.get().af_set_unique(c_pointer(out.arr), a.arr, c_bool_t(is_sorted))) + return out
+ +
[docs]def set_union(a, b, is_unique=False): + """ + Find the union of two arrays. + + Parameters + ---------- + a : af.Array + A 1D arrayfire array. + b : af.Array + A 1D arrayfire array. + is_unique: optional: bool. default: False + Specifies if the both inputs contain unique elements. + + Returns + ------- + out: af.Array + an array values after performing the union of `a` and `b`. + """ + out = Array() + safe_call(backend.get().af_set_union(c_pointer(out.arr), a.arr, b.arr, c_bool_t(is_unique))) + return out
+ +
[docs]def set_intersect(a, b, is_unique=False): + """ + Find the intersect of two arrays. + + Parameters + ---------- + a : af.Array + A 1D arrayfire array. + b : af.Array + A 1D arrayfire array. + is_unique: optional: bool. default: False + Specifies if the both inputs contain unique elements. + + Returns + ------- + out: af.Array + an array values after performing the intersect of `a` and `b`. + """ + out = Array() + safe_call(backend.get().af_set_intersect(c_pointer(out.arr), a.arr, b.arr, c_bool_t(is_unique))) + return out
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/arith.html b/_modules/arrayfire/arith.html new file mode 100644 index 000000000..151e62bdd --- /dev/null +++ b/_modules/arrayfire/arith.html @@ -0,0 +1,1221 @@ + + + + + + + + arrayfire.arith — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.arith

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Math functions (sin, sqrt, exp, etc).
+"""
+
+from .library import *
+from .array import *
+from .bcast import _bcast_var
+from .util import _is_number
+
+def _arith_binary_func(lhs, rhs, c_func):
+    out = Array()
+
+    is_left_array = isinstance(lhs, Array)
+    is_right_array = isinstance(rhs, Array)
+
+    if not (is_left_array or is_right_array):
+        raise TypeError("Atleast one input needs to be of type arrayfire.array")
+
+    elif (is_left_array and is_right_array):
+        safe_call(c_func(c_pointer(out.arr), lhs.arr, rhs.arr, _bcast_var.get()))
+
+    elif (_is_number(rhs)):
+        ldims = dim4_to_tuple(lhs.dims())
+        rty = implicit_dtype(rhs, lhs.type())
+        other = Array()
+        other.arr = constant_array(rhs, ldims[0], ldims[1], ldims[2], ldims[3], rty)
+        safe_call(c_func(c_pointer(out.arr), lhs.arr, other.arr, _bcast_var.get()))
+
+    else:
+        rdims = dim4_to_tuple(rhs.dims())
+        lty = implicit_dtype(lhs, rhs.type())
+        other = Array()
+        other.arr = constant_array(lhs, rdims[0], rdims[1], rdims[2], rdims[3], lty)
+        safe_call(c_func(c_pointer(out.arr), other.arr, rhs.arr, _bcast_var.get()))
+
+    return out
+
+def _arith_unary_func(a, c_func):
+    out = Array()
+    safe_call(c_func(c_pointer(out.arr), a.arr))
+    return out
+
+
[docs]def cast(a, dtype): + """ + Cast an array to a specified type + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + dtype: af.Dtype + Must be one of the following: + - Dtype.f32 for float + - Dtype.f64 for double + - Dtype.b8 for bool + - Dtype.u8 for unsigned char + - Dtype.s32 for signed 32 bit integer + - Dtype.u32 for unsigned 32 bit integer + - Dtype.s64 for signed 64 bit integer + - Dtype.u64 for unsigned 64 bit integer + - Dtype.c32 for 32 bit complex number + - Dtype.c64 for 64 bit complex number + Returns + -------- + out : af.Array + array containing the values from `a` after converting to `dtype`. + """ + out=Array() + safe_call(backend.get().af_cast(c_pointer(out.arr), a.arr, dtype.value)) + return out
+ +
[docs]def minof(lhs, rhs): + """ + Find the minimum value of two inputs at each location. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + array containing the minimum value at each location of the inputs. + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_minof)
+ +
[docs]def maxof(lhs, rhs): + """ + Find the maximum value of two inputs at each location. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + array containing the maximum value at each location of the inputs. + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_maxof)
+ +
[docs]def clamp(val, low, high): + """ + Clamp the input value between low and high + + + Parameters + ---------- + val : af.Array + Multi dimensional arrayfire array to be clamped. + + low : af.Array or scalar + Multi dimensional arrayfire array or a scalar number denoting the lower value(s). + + high : af.Array or scalar + Multi dimensional arrayfire array or a scalar number denoting the higher value(s). + """ + out = Array() + + is_low_array = isinstance(low, Array) + is_high_array = isinstance(high, Array) + + vdims = dim4_to_tuple(val.dims()) + vty = val.type() + + if not is_low_array: + low_arr = constant_array(low, vdims[0], vdims[1], vdims[2], vdims[3], vty) + else: + low_arr = low.arr + + if not is_high_array: + high_arr = constant_array(high, vdims[0], vdims[1], vdims[2], vdims[3], vty) + else: + high_arr = high.arr + + safe_call(backend.get().af_clamp(c_pointer(out.arr), val.arr, low_arr, high_arr, _bcast_var.get())) + + return out
+ +
[docs]def mod(lhs, rhs): + """ + Find the modulus. + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + Returns + -------- + out : af.Array + Contains the moduli after dividing each value of lhs` with those in `rhs`. + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_mod)
+ +
[docs]def rem(lhs, rhs): + """ + Find the remainder. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + Contains the remainders after dividing each value of lhs` with those in `rhs`. + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_rem)
+ +
[docs]def abs(a): + """ + Find the absolute values. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + Contains the absolute values of the inputs. + """ + return _arith_unary_func(a, backend.get().af_abs)
+ +
[docs]def arg(a): + """ + Find the theta value of the inputs in polar co-ordinates. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + Contains the theta values. + """ + return _arith_unary_func(a, backend.get().af_arg)
+ +
[docs]def sign(a): + """ + Find the sign of the inputs. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing 1 for negative values, 0 otherwise. + """ + return _arith_unary_func(a, backend.get().af_sign)
+ +
[docs]def round(a): + """ + Round the values to nearest integer. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the values rounded to nearest integer. + """ + return _arith_unary_func(a, backend.get().af_round)
+ +
[docs]def trunc(a): + """ + Round the values towards zero. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the truncated values. + """ + return _arith_unary_func(a, backend.get().af_trunc)
+ +
[docs]def floor(a): + """ + Round the values towards a smaller integer. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the floored values. + """ + return _arith_unary_func(a, backend.get().af_floor)
+ +
[docs]def ceil(a): + """ + Round the values towards a bigger integer. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the ceiled values. + """ + return _arith_unary_func(a, backend.get().af_ceil)
+ +
[docs]def hypot(lhs, rhs): + """ + Find the value of the hypotunese. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + Contains the value of `sqrt(lhs**2, rhs**2)`. + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_hypot)
+ +
[docs]def sin(a): + """ + Sine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the sine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_sin)
+ +
[docs]def cos(a): + """ + Cosine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the cosine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_cos)
+ +
[docs]def tan(a): + """ + Tangent of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the tangent of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_tan)
+ +
[docs]def asin(a): + """ + Arc Sine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc sine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_asin)
+ +
[docs]def acos(a): + """ + Arc Cosine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc cosine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_acos)
+ +
[docs]def atan(a): + """ + Arc Tangent of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc tangent of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_atan)
+ +
[docs]def atan2(lhs, rhs): + """ + Find the arc tan using two values. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + Contains the value arc tan values where: + - `lhs` contains the sine values. + - `rhs` contains the cosine values. + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_atan2)
+ +
[docs]def cplx(lhs, rhs=None): + """ + Create a complex array from real inputs. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : optional: af.Array or scalar. default: None. + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + Contains complex values whose + - real values contain values from `lhs` + - imaginary values contain values from `rhs` (0 if `rhs` is None) + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + if rhs is None: + return _arith_unary_func(lhs, backend.get().af_cplx) + else: + return _arith_binary_func(lhs, rhs, backend.get().af_cplx2)
+ +
[docs]def real(a): + """ + Find the real values of the input. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the real values from `a`. + + """ + return _arith_unary_func(a, backend.get().af_real)
+ +
[docs]def imag(a): + """ + Find the imaginary values of the input. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the imaginary values from `a`. + """ + return _arith_unary_func(a, backend.get().af_imag)
+ +
[docs]def conjg(a): + """ + Find the complex conjugate values of the input. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing copmplex conjugate values from `a`. + """ + return _arith_unary_func(a, backend.get().af_conjg)
+ +
[docs]def sinh(a): + """ + Hyperbolic Sine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the hyperbolic sine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_sinh)
+ +
[docs]def cosh(a): + """ + Hyperbolic Cosine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the hyperbolic cosine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_cosh)
+ +
[docs]def tanh(a): + """ + Hyperbolic Tangent of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the hyperbolic tangent of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_tanh)
+ +
[docs]def asinh(a): + """ + Arc Hyperbolic Sine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc hyperbolic sine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_asinh)
+ +
[docs]def acosh(a): + """ + Arc Hyperbolic Cosine of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc hyperbolic cosine of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_acosh)
+ +
[docs]def atanh(a): + """ + Arc Hyperbolic Tangent of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the arc hyperbolic tangent of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_atanh)
+ +
[docs]def root(lhs, rhs): + """ + Find the root values of two inputs at each location. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + array containing the value of `lhs ** (1/rhs)` + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_root)
+ +
[docs]def pow(lhs, rhs): + """ + Find the power of two inputs at each location. + + Parameters + ---------- + lhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + rhs : af.Array or scalar + Multi dimensional arrayfire array or a scalar number. + + Returns + -------- + out : af.Array + array containing the value of `lhs ** (rhs)` + + Note + ------- + - Atleast one of `lhs` and `rhs` needs to be af.Array. + - If `lhs` and `rhs` are both af.Array, they must be of same size. + """ + return _arith_binary_func(lhs, rhs, backend.get().af_pow)
+ +
[docs]def pow2(a): + """ + Raise 2 to the power of each element in input. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array where each element is 2 raised to power of the corresponding value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_pow2)
+ +
[docs]def sigmoid(a): + """ + Raise 2 to the power of each element in input. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array where each element is outout of a sigmoid function for the corresponding value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_sigmoid)
+ +
[docs]def exp(a): + """ + Exponential of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the exponential of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_exp)
+ +
[docs]def expm1(a): + """ + Exponential of each element in the array minus 1. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the exponential of each value from `a`. + + Note + ------- + - `a` must not be complex. + - This function provides a more stable result for small values of `a`. + """ + return _arith_unary_func(a, backend.get().af_expm1)
+ +
[docs]def erf(a): + """ + Error function of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the error function of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_erf)
+ +
[docs]def erfc(a): + """ + Complementary error function of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the complementary error function of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_erfc)
+ +
[docs]def log(a): + """ + Natural logarithm of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the natural logarithm of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_log)
+ +
[docs]def log1p(a): + """ + Logarithm of each element in the array plus 1. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the the values of `log(a) + 1` + + Note + ------- + - `a` must not be complex. + - This function provides a more stable result for small values of `a`. + """ + return _arith_unary_func(a, backend.get().af_log1p)
+ +
[docs]def log10(a): + """ + Logarithm base 10 of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the logarithm base 10 of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_log10)
+ +
[docs]def log2(a): + """ + Logarithm base 2 of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the logarithm base 2 of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_log2)
+ +
[docs]def sqrt(a): + """ + Square root of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the square root of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_sqrt)
+ +
[docs]def rsqrt(a): + """ + Reciprocal or inverse square root of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the inverse square root of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_rsqrt)
+ +
[docs]def cbrt(a): + """ + Cube root of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the cube root of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_cbrt)
+ +
[docs]def factorial(a): + """ + factorial of each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the factorial of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_factorial)
+ +
[docs]def tgamma(a): + """ + Performs the gamma function for each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the output of gamma function of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_tgamma)
+ +
[docs]def lgamma(a): + """ + Performs the logarithm of gamma function for each element in the array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the output of logarithm of gamma function of each value from `a`. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_lgamma)
+ +
[docs]def iszero(a): + """ + Check if each element of the input is zero. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the output after checking if each value of `a` is 0. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_iszero)
+ +
[docs]def isinf(a): + """ + Check if each element of the input is infinity. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the output after checking if each value of `a` is inifnite. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_isinf)
+ +
[docs]def isnan(a): + """ + Check if each element of the input is NaN. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array. + + Returns + -------- + out : af.Array + array containing the output after checking if each value of `a` is NaN. + + Note + ------- + `a` must not be complex. + """ + return _arith_unary_func(a, backend.get().af_isnan)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/array.html b/_modules/arrayfire/array.html new file mode 100644 index 000000000..101d2675a --- /dev/null +++ b/_modules/arrayfire/array.html @@ -0,0 +1,1597 @@ + + + + + + + + arrayfire.array — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.array

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Array class and helper functions.
+"""
+
+import inspect
+import os
+from .library import *
+from .util import *
+from .util import _is_number
+from .bcast import _bcast_var
+from .base import *
+from .index import *
+from .index import _Index4
+
+_is_running_in_py_charm = "PYCHARM_HOSTED" in os.environ
+
+_display_dims_limit = None
+
+
[docs]def set_display_dims_limit(*dims): + """ + Sets the dimension limit after which array's data won't get + presented to the result of str(arr). + + Default is None, which means there is no limit. + + Parameters + ---------- + *dims : dimension limit args + + Example + ------- + set_display_dims_limit(10, 10, 10, 10) + + """ + global _display_dims_limit + _display_dims_limit = dims
+ +
[docs]def get_display_dims_limit(): + """ + Gets the dimension limit after which array's data won't get + presented to the result of str(arr). + + Default is None, which means there is no limit. + + Returns + ----------- + - tuple of the current limit + - None is there is no limit + + Example + ------- + get_display_dims_limit() + # None + set_display_dims_limit(10, 10, 10, 10) + get_display_dims_limit() + # (10, 10, 10, 10) + + """ + return _display_dims_limit
+ +def _in_display_dims_limit(dims): + if _is_running_in_py_charm: + return False + if _display_dims_limit is not None: + limit_len = len(_display_dims_limit) + dim_len = len(dims) + if dim_len > limit_len: + return False + for i in range(dim_len): + if dims[i] > _display_dims_limit[i]: + return False + return True + +def _create_array(buf, numdims, idims, dtype, is_device): + out_arr = c_void_ptr_t(0) + c_dims = dim4(idims[0], idims[1], idims[2], idims[3]) + if (not is_device): + safe_call(backend.get().af_create_array(c_pointer(out_arr), c_void_ptr_t(buf), + numdims, c_pointer(c_dims), dtype.value)) + else: + safe_call(backend.get().af_device_array(c_pointer(out_arr), c_void_ptr_t(buf), + numdims, c_pointer(c_dims), dtype.value)) + return out_arr + +def _create_strided_array(buf, numdims, idims, dtype, is_device, offset, strides): + out_arr = c_void_ptr_t(0) + c_dims = dim4(idims[0], idims[1], idims[2], idims[3]) + if offset is None: + offset = 0 + offset = c_dim_t(offset) + if strides is None: + strides = (1, idims[0], idims[0]*idims[1], idims[0]*idims[1]*idims[2]) + while len(strides) < 4: + strides = strides + (strides[-1],) + strides = dim4(strides[0], strides[1], strides[2], strides[3]) + if is_device: + location = Source.device + else: + location = Source.host + safe_call(backend.get().af_create_strided_array(c_pointer(out_arr), c_void_ptr_t(buf), + offset, numdims, c_pointer(c_dims), + c_pointer(strides), dtype.value, + location.value)) + return out_arr + +def _create_empty_array(numdims, idims, dtype): + out_arr = c_void_ptr_t(0) + + if numdims == 0: return out_arr + + c_dims = dim4(idims[0], idims[1], idims[2], idims[3]) + safe_call(backend.get().af_create_handle(c_pointer(out_arr), + numdims, c_pointer(c_dims), dtype.value)) + return out_arr + +
[docs]def constant_array(val, d0, d1=None, d2=None, d3=None, dtype=Dtype.f32): + """ + Internal function to create a C array. Should not be used externall. + """ + + if not isinstance(dtype, c_int_t): + if isinstance(dtype, int): + dtype = c_int_t(dtype) + elif isinstance(dtype, Dtype): + dtype = c_int_t(dtype.value) + else: + raise TypeError("Invalid dtype") + + out = c_void_ptr_t(0) + dims = dim4(d0, d1, d2, d3) + + if isinstance(val, complex): + c_real = c_double_t(val.real) + c_imag = c_double_t(val.imag) + + if (dtype.value != Dtype.c32.value and dtype.value != Dtype.c64.value): + dtype = Dtype.c32.value + + safe_call(backend.get().af_constant_complex(c_pointer(out), c_real, c_imag, + 4, c_pointer(dims), dtype)) + elif dtype.value == Dtype.s64.value: + c_val = c_longlong_t(val.real) + safe_call(backend.get().af_constant_long(c_pointer(out), c_val, 4, c_pointer(dims))) + elif dtype.value == Dtype.u64.value: + c_val = c_ulonglong_t(val.real) + safe_call(backend.get().af_constant_ulong(c_pointer(out), c_val, 4, c_pointer(dims))) + else: + c_val = c_double_t(val) + safe_call(backend.get().af_constant(c_pointer(out), c_val, 4, c_pointer(dims), dtype)) + + return out
+ + +def _binary_func(lhs, rhs, c_func): + out = Array() + other = rhs + + if (_is_number(rhs)): + ldims = dim4_to_tuple(lhs.dims()) + rty = implicit_dtype(rhs, lhs.type()) + other = Array() + other.arr = constant_array(rhs, ldims[0], ldims[1], ldims[2], ldims[3], rty.value) + elif not isinstance(rhs, Array): + raise TypeError("Invalid parameter to binary function") + + safe_call(c_func(c_pointer(out.arr), lhs.arr, other.arr, _bcast_var.get())) + + return out + +def _binary_funcr(lhs, rhs, c_func): + out = Array() + other = lhs + + if (_is_number(lhs)): + rdims = dim4_to_tuple(rhs.dims()) + lty = implicit_dtype(lhs, rhs.type()) + other = Array() + other.arr = constant_array(lhs, rdims[0], rdims[1], rdims[2], rdims[3], lty.value) + elif not isinstance(lhs, Array): + raise TypeError("Invalid parameter to binary function") + + c_func(c_pointer(out.arr), other.arr, rhs.arr, _bcast_var.get()) + + return out + +def _ctype_to_lists(ctype_arr, dim, shape, offset=0): + if (dim == 0): + return list(ctype_arr[offset : offset + shape[0]]) + else: + dim_len = shape[dim] + res = [[]] * dim_len + for n in range(dim_len): + res[n] = _ctype_to_lists(ctype_arr, dim - 1, shape, offset) + offset += shape[0] + return res + +def _slice_to_length(key, dim): + tkey = [key.start, key.stop, key.step] + + if tkey[0] is None: + tkey[0] = 0 + elif tkey[0] < 0: + tkey[0] = dim - tkey[0] + + if tkey[1] is None: + tkey[1] = dim + elif tkey[1] < 0: + tkey[1] = dim - tkey[1] + + if tkey[2] is None: + tkey[2] = 1 + + return int(((tkey[1] - tkey[0] - 1) / tkey[2]) + 1) + +def _get_info(dims, buf_len): + elements = 1 + numdims = 0 + if dims: + numdims = len(dims) + idims = [1]*4 + for i in range(numdims): + elements *= dims[i] + idims[i] = dims[i] + elif (buf_len != 0): + idims = [buf_len, 1, 1, 1] + numdims = 1 + else: + raise RuntimeError("Invalid size") + + return numdims, idims + + +def _get_indices(key): + inds = _Index4() + if isinstance(key, tuple): + n_idx = len(key) + for n in range(n_idx): + inds[n] = Index(key[n]) + else: + inds[0] = Index(key) + + return inds + +def _get_assign_dims(key, idims): + + dims = [1]*4 + + for n in range(len(idims)): + dims[n] = idims[n] + + if _is_number(key): + dims[0] = 1 + return dims + elif isinstance(key, slice): + dims[0] = _slice_to_length(key, idims[0]) + return dims + elif isinstance(key, ParallelRange): + dims[0] = _slice_to_length(key.S, idims[0]) + return dims + elif isinstance(key, BaseArray): + # If the array is boolean take only the number of nonzeros + if(key.dtype() is Dtype.b8): + dims[0] = int(sum(key)) + else: + dims[0] = key.elements() + return dims + elif isinstance(key, tuple): + n_inds = len(key) + + for n in range(n_inds): + if (_is_number(key[n])): + dims[n] = 1 + elif (isinstance(key[n], BaseArray)): + # If the array is boolean take only the number of nonzeros + if(key[n].dtype() is Dtype.b8): + dims[n] = int(sum(key[n])) + else: + dims[n] = key[n].elements() + elif (isinstance(key[n], slice)): + dims[n] = _slice_to_length(key[n], idims[n]) + elif (isinstance(key[n], ParallelRange)): + dims[n] = _slice_to_length(key[n].S, idims[n]) + else: + raise IndexError("Invalid type while assigning to arrayfire.array") + + return dims + else: + raise IndexError("Invalid type while assigning to arrayfire.array") + +
[docs]def transpose(a, conj=False): + """ + Perform the transpose on an input. + + Parameters + ----------- + a : af.Array + Multi dimensional arrayfire array. + + conj : optional: bool. default: False. + Flag to specify if a complex conjugate needs to applied for complex inputs. + + Returns + -------- + out : af.Array + Containing the tranpose of `a` for all batches. + + """ + out = Array() + safe_call(backend.get().af_transpose(c_pointer(out.arr), a.arr, conj)) + return out
+ +
[docs]def transpose_inplace(a, conj=False): + """ + Perform inplace transpose on an input. + + Parameters + ----------- + a : af.Array + - Multi dimensional arrayfire array. + - Contains transposed values on exit. + + conj : optional: bool. default: False. + Flag to specify if a complex conjugate needs to applied for complex inputs. + + Note + ------- + Input `a` needs to be a square matrix or a batch of square matrices. + + """ + safe_call(backend.get().af_transpose_inplace(a.arr, conj))
+ +
[docs]class Array(BaseArray): + + """ + A multi dimensional array container. + + Parameters + ---------- + src : optional: array.array, list or C buffer. default: None. + - When `src` is `array.array` or `list`, the data is copied to create the Array() + - When `src` is None, an empty buffer is created. + + dims : optional: tuple of ints. default: (0,) + - When using the default values of `dims`, the dims are caclulated as `len(src)` + + dtype: optional: str or arrayfire.Dtype. default: None. + - if str, must be one of the following: + - 'f' for float + - 'd' for double + - 'b' for bool + - 'B' for unsigned char + - 'h' for signed 16 bit integer + - 'H' for unsigned 16 bit integer + - 'i' for signed 32 bit integer + - 'I' for unsigned 32 bit integer + - 'l' for signed 64 bit integer + - 'L' for unsigned 64 bit integer + - 'F' for 32 bit complex number + - 'D' for 64 bit complex number + + - if arrayfire.Dtype, must be one of the following: + - Dtype.f32 for float + - Dtype.f64 for double + - Dtype.b8 for bool + - Dtype.u8 for unsigned char + - Dtype.s16 for signed 16 bit integer + - Dtype.u16 for unsigned 16 bit integer + - Dtype.s32 for signed 32 bit integer + - Dtype.u32 for unsigned 32 bit integer + - Dtype.s64 for signed 64 bit integer + - Dtype.u64 for unsigned 64 bit integer + - Dtype.c32 for 32 bit complex number + - Dtype.c64 for 64 bit complex number + + - if None, Dtype.f32 is assumed + + Attributes + ----------- + arr: ctypes.c_void_p + ctypes variable containing af_array from arrayfire library. + + Examples + -------- + + Creating an af.Array() from array.array() + + >>> import arrayfire as af + >>> import array + >>> a = array.array('f', (1, 2, 3, 4)) + >>> b = af.Array(a, (2,2)) + >>> af.display(b) + [2 2 1 1] + 1.0000 3.0000 + 2.0000 4.0000 + + Creating an af.Array() from a list + + >>> import arrayfire as af + >>> import array + >>> a = [1, 2, 3, 4] + >>> b = af.Array(a) + >>> af.display(b) + [4 1 1 1] + 1.0000 + 2.0000 + 3.0000 + 4.0000 + + Creating an af.Array() from numpy.array() + + >>> import numpy as np + >>> import arrayfire as af + >>> a = np.random.random((2,2)) + >>> a + array([[ 0.33042524, 0.36135449], + [ 0.86748649, 0.42199135]]) + >>> b = af.Array(a.ctypes.data, a.shape, a.dtype.char) + >>> af.display(b) + [2 2 1 1] + 0.3304 0.8675 + 0.3614 0.4220 + + Note + ----- + - The class is currently limited to 4 dimensions. + - arrayfire.Array() uses column major format. + - numpy uses row major format by default which can cause issues during conversion + + """ + + # Numpy checks this attribute to know which class handles binary builtin operations, such as __add__. + # Setting to such a high value should make sure that arrayfire has priority over + # other classes, ensuring that e.g. numpy.float32(1)*arrayfire.randu(3) is handled by + # arrayfire's __radd__() instead of numpy's __add__() + __array_priority__ = 30 + + def __init__(self, src=None, dims=None, dtype=None, is_device=False, offset=None, strides=None): + + super(Array, self).__init__() + + buf=None + buf_len=0 + + if dtype is not None: + if isinstance(dtype, str): + type_char = dtype + else: + type_char = to_typecode[dtype.value] + else: + type_char = None + + _type_char='f' + + if src is not None: + + if (isinstance(src, Array)): + safe_call(backend.get().af_retain_array(c_pointer(self.arr), src.arr)) + return + + host = __import__("array") + + if isinstance(src, host.array): + buf,buf_len = src.buffer_info() + _type_char = src.typecode + numdims, idims = _get_info(dims, buf_len) + elif isinstance(src, list): + tmp = host.array('f', src) + buf,buf_len = tmp.buffer_info() + _type_char = tmp.typecode + numdims, idims = _get_info(dims, buf_len) + elif isinstance(src, int) or isinstance(src, c_void_ptr_t): + buf = src if not isinstance(src, c_void_ptr_t) else src.value + + numdims, idims = _get_info(dims, buf_len) + + elements = 1 + for dim in idims: + elements *= dim + + if (elements == 0): + raise RuntimeError("Expected dims when src is data pointer") + + if (type_char is None): + raise TypeError("Expected type_char when src is data pointer") + + _type_char = type_char + + else: + raise TypeError("src is an object of unsupported class") + + if (type_char is not None and + type_char != _type_char): + raise TypeError("Can not create array of requested type from input data type") + if(offset is None and strides is None): + self.arr = _create_array(buf, numdims, idims, to_dtype[_type_char], is_device) + else: + self.arr = _create_strided_array(buf, numdims, idims, + to_dtype[_type_char], + is_device, offset, strides) + + else: + + if type_char is None: + type_char = 'f' + + numdims = len(dims) if dims else 0 + + idims = [1] * 4 + for n in range(numdims): + idims[n] = dims[n] + + self.arr = _create_empty_array(numdims, idims, to_dtype[type_char]) + +
[docs] def as_type(self, ty): + """ + Cast current array to a specified data type + + Parameters + ---------- + ty : Return data type + """ + return cast(self, ty)
+ +
[docs] def copy(self): + """ + Performs a deep copy of the array. + + Returns + ------- + out: af.Array() + An identical copy of self. + """ + out = Array() + safe_call(backend.get().af_copy_array(c_pointer(out.arr), self.arr)) + return out
+ + def __del__(self): + """ + Release the C array when going out of scope + """ + if self.arr.value: + backend.get().af_release_array(self.arr) + self.arr.value = 0 + +
[docs] def device_ptr(self): + """ + Return the device pointer exclusively held by the array. + + Returns + -------- + ptr : int + Contains location of the device pointer + + Note + ---- + - This can be used to integrate with custom C code and / or PyCUDA or PyOpenCL. + - Implies `af.device.lock_array()`. The device pointer of `a` is not freed by memory manager until `unlock_device_ptr()` is called. + - No other arrays will share the same device pointer. + - A copy of the memory is done if multiple arrays share the same memory or the array is not the owner of the memory. + - In case of a copy the return value points to the newly allocated memory which is now exclusively owned by the array. + """ + ptr = c_void_ptr_t(0) + backend.get().af_get_device_ptr(c_pointer(ptr), self.arr) + return ptr.value
+ +
[docs] def raw_ptr(self): + """ + Return the device pointer held by the array. + + Returns + -------- + ptr : int + Contains location of the device pointer + + Note + ---- + - This can be used to integrate with custom C code and / or PyCUDA or PyOpenCL. + - No mem copy is peformed, this function returns the raw device pointer. + - This pointer may be shared with other arrays. Use this function with caution. + - In particular the JIT compiler will not be aware of the shared arrays. + - This results in JITed operations not being immediately visible through the other array. + """ + ptr = c_void_ptr_t(0) + backend.get().af_get_raw_ptr(c_pointer(ptr), self.arr) + return ptr.value
+ +
[docs] def offset(self): + """ + Return the offset, of the first element relative to the raw pointer. + + Returns + -------- + offset : int + The offset in number of elements + """ + offset = c_dim_t(0) + safe_call(backend.get().af_get_offset(c_pointer(offset), self.arr)) + return offset.value
+ +
[docs] def strides(self): + """ + Return the distance in bytes between consecutive elements for each dimension. + + Returns + -------- + strides : tuple + The strides for each dimension + """ + s0 = c_dim_t(0) + s1 = c_dim_t(0) + s2 = c_dim_t(0) + s3 = c_dim_t(0) + safe_call(backend.get().af_get_strides(c_pointer(s0), c_pointer(s1), + c_pointer(s2), c_pointer(s3), self.arr)) + strides = (s0.value,s1.value,s2.value,s3.value) + return strides[:self.numdims()]
+ +
[docs] def elements(self): + """ + Return the number of elements in the array. + """ + num = c_dim_t(0) + safe_call(backend.get().af_get_elements(c_pointer(num), self.arr)) + return num.value
+ + def __len__(self): + return(self.elements()) + +
[docs] def allocated(self): + """ + Returns the number of bytes allocated by the memory manager for the array. + """ + num = c_size_t(0) + safe_call(backend.get().af_get_allocated_bytes(c_pointer(num), self.arr)) + return num.value
+ +
[docs] def dtype(self): + """ + Return the data type as a arrayfire.Dtype enum value. + """ + dty = c_int_t(Dtype.f32.value) + safe_call(backend.get().af_get_type(c_pointer(dty), self.arr)) + return to_dtype[to_typecode[dty.value]]
+ +
[docs] def type(self): + """ + Return the data type as an int. + """ + return self.dtype().value
+ + @property + def T(self): + """ + Return the transpose of the array + """ + return transpose(self, False) + + @property + def H(self): + """ + Return the hermitian transpose of the array + """ + return transpose(self, True) + +
[docs] def dims(self): + """ + Return the shape of the array as a tuple. + """ + d0 = c_dim_t(0) + d1 = c_dim_t(0) + d2 = c_dim_t(0) + d3 = c_dim_t(0) + safe_call(backend.get().af_get_dims(c_pointer(d0), c_pointer(d1), + c_pointer(d2), c_pointer(d3), self.arr)) + dims = (d0.value,d1.value,d2.value,d3.value) + return dims[:self.numdims()]
+ + @property + def shape(self): + """ + The shape of the array + """ + return self.dims() + +
[docs] def numdims(self): + """ + Return the number of dimensions of the array. + """ + nd = c_uint_t(0) + safe_call(backend.get().af_get_numdims(c_pointer(nd), self.arr)) + return nd.value
+ +
[docs] def is_empty(self): + """ + Check if the array is empty i.e. it has no elements. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_empty(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_scalar(self): + """ + Check if the array is scalar i.e. it has only one element. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_scalar(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_row(self): + """ + Check if the array is a row i.e. it has a shape of (1, cols). + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_row(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_column(self): + """ + Check if the array is a column i.e. it has a shape of (rows, 1). + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_column(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_vector(self): + """ + Check if the array is a vector i.e. it has a shape of one of the following: + - (rows, 1) + - (1, cols) + - (1, 1, vols) + - (1, 1, 1, batch) + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_vector(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_sparse(self): + """ + Check if the array is a sparse matrix. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_sparse(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_complex(self): + """ + Check if the array is of complex type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_complex(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_real(self): + """ + Check if the array is not of complex type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_real(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_double(self): + """ + Check if the array is of double precision floating point type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_double(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_single(self): + """ + Check if the array is of single precision floating point type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_single(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_half(self): + """ + Check if the array is of half floating point type (fp16). + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_half(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_real_floating(self): + """ + Check if the array is real and of floating point type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_realfloating(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_floating(self): + """ + Check if the array is of floating point type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_floating(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_integer(self): + """ + Check if the array is of integer type. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_integer(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_bool(self): + """ + Check if the array is of type b8. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_bool(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_linear(self): + """ + Check if all elements of the array are contiguous. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_linear(c_pointer(res), self.arr)) + return res.value
+ +
[docs] def is_owner(self): + """ + Check if the array owns the raw pointer or is a derived array. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_owner(c_pointer(res), self.arr)) + return res.value
+ + def __add__(self, other): + """ + Return self + other. + """ + return _binary_func(self, other, backend.get().af_add) + + def __iadd__(self, other): + """ + Perform self += other. + """ + self = _binary_func(self, other, backend.get().af_add) + return self + + def __radd__(self, other): + """ + Return other + self. + """ + return _binary_funcr(other, self, backend.get().af_add) + + def __sub__(self, other): + """ + Return self - other. + """ + return _binary_func(self, other, backend.get().af_sub) + + def __isub__(self, other): + """ + Perform self -= other. + """ + self = _binary_func(self, other, backend.get().af_sub) + return self + + def __rsub__(self, other): + """ + Return other - self. + """ + return _binary_funcr(other, self, backend.get().af_sub) + + def __mul__(self, other): + """ + Return self * other. + """ + return _binary_func(self, other, backend.get().af_mul) + + def __imul__(self, other): + """ + Perform self *= other. + """ + self = _binary_func(self, other, backend.get().af_mul) + return self + + def __rmul__(self, other): + """ + Return other * self. + """ + return _binary_funcr(other, self, backend.get().af_mul) + + def __truediv__(self, other): + """ + Return self / other. + """ + return _binary_func(self, other, backend.get().af_div) + + def __itruediv__(self, other): + """ + Perform self /= other. + """ + self = _binary_func(self, other, backend.get().af_div) + return self + + def __rtruediv__(self, other): + """ + Return other / self. + """ + return _binary_funcr(other, self, backend.get().af_div) + + def __div__(self, other): + """ + Return self / other. + """ + return _binary_func(self, other, backend.get().af_div) + + def __idiv__(self, other): + """ + Perform other / self. + """ + self = _binary_func(self, other, backend.get().af_div) + return self + + def __rdiv__(self, other): + """ + Return other / self. + """ + return _binary_funcr(other, self, backend.get().af_div) + + def __mod__(self, other): + """ + Return self % other. + """ + return _binary_func(self, other, backend.get().af_mod) + + def __imod__(self, other): + """ + Perform self %= other. + """ + self = _binary_func(self, other, backend.get().af_mod) + return self + + def __rmod__(self, other): + """ + Return other % self. + """ + return _binary_funcr(other, self, backend.get().af_mod) + + def __pow__(self, other): + """ + Return self ** other. + """ + return _binary_func(self, other, backend.get().af_pow) + + def __ipow__(self, other): + """ + Perform self **= other. + """ + self = _binary_func(self, other, backend.get().af_pow) + return self + + def __rpow__(self, other): + """ + Return other ** self. + """ + return _binary_funcr(other, self, backend.get().af_pow) + + def __lt__(self, other): + """ + Return self < other. + """ + return _binary_func(self, other, backend.get().af_lt) + + def __gt__(self, other): + """ + Return self > other. + """ + return _binary_func(self, other, backend.get().af_gt) + + def __le__(self, other): + """ + Return self <= other. + """ + return _binary_func(self, other, backend.get().af_le) + + def __ge__(self, other): + """ + Return self >= other. + """ + return _binary_func(self, other, backend.get().af_ge) + + def __eq__(self, other): + """ + Return self == other. + """ + return _binary_func(self, other, backend.get().af_eq) + + def __ne__(self, other): + """ + Return self != other. + """ + return _binary_func(self, other, backend.get().af_neq) + + def __and__(self, other): + """ + Return self & other. + """ + return _binary_func(self, other, backend.get().af_bitand) + + def __iand__(self, other): + """ + Perform self &= other. + """ + self = _binary_func(self, other, backend.get().af_bitand) + return self + + def __or__(self, other): + """ + Return self | other. + """ + return _binary_func(self, other, backend.get().af_bitor) + + def __ior__(self, other): + """ + Perform self |= other. + """ + self = _binary_func(self, other, backend.get().af_bitor) + return self + + def __xor__(self, other): + """ + Return self ^ other. + """ + return _binary_func(self, other, backend.get().af_bitxor) + + def __ixor__(self, other): + """ + Perform self ^= other. + """ + self = _binary_func(self, other, backend.get().af_bitxor) + return self + + def __lshift__(self, other): + """ + Return self << other. + """ + return _binary_func(self, other, backend.get().af_bitshiftl) + + def __ilshift__(self, other): + """ + Perform self <<= other. + """ + self = _binary_func(self, other, backend.get().af_bitshiftl) + return self + + def __rshift__(self, other): + """ + Return self >> other. + """ + return _binary_func(self, other, backend.get().af_bitshiftr) + + def __irshift__(self, other): + """ + Perform self >>= other. + """ + self = _binary_func(self, other, backend.get().af_bitshiftr) + return self + + def __neg__(self): + """ + Return -self + """ + return 0 - self + + def __pos__(self): + """ + Return +self + """ + return self + + def __invert__(self): + """ + Return ~self + """ + out = Array() + safe_call(backend.get().af_bitnot(c_pointer(out.arr), self.arr)) + return out + +
[docs] def logical_not(self): + """ + Return ~self + """ + out = Array() + safe_call(backend.get().af_not(c_pointer(out.arr), self.arr)) + return out
+ +
[docs] def logical_and(self, other): + """ + Return self && other. + """ + out = Array() + safe_call(backend.get().af_and(c_pointer(out.arr), self.arr, other.arr)) #TODO: bcast var? + return out
+ +
[docs] def logical_or(self, other): + """ + Return self || other. + """ + out = Array() + safe_call(backend.get().af_or(c_pointer(out.arr), self.arr, other.arr)) #TODO: bcast var? + return out
+ + def __nonzero__(self): + return self != 0 + + # TODO: + # def __abs__(self): + # return self + + def __getitem__(self, key): + """ + Return self[key] + + Note + ---- + Ellipsis not supported as key + """ + try: + out = Array() + n_dims = self.numdims() + + if (isinstance(key, Array) and key.type() == Dtype.b8.value): + n_dims = 1 + if (count(key) == 0): + return out + + inds = _get_indices(key) + + safe_call(backend.get().af_index_gen(c_pointer(out.arr), + self.arr, c_dim_t(n_dims), inds.pointer)) + return out + except RuntimeError as e: + raise IndexError(str(e)) + + + def __setitem__(self, key, val): + """ + Perform self[key] = val + + Note + ---- + Ellipsis not supported as key + """ + try: + n_dims = self.numdims() + + is_boolean_idx = isinstance(key, Array) and key.type() == Dtype.b8.value + + if (is_boolean_idx): + n_dims = 1 + num = count(key) + if (num == 0): + return + + if (_is_number(val)): + tdims = _get_assign_dims(key, self.dims()) + if (is_boolean_idx): + n_dims = 1 + other_arr = constant_array(val, int(num), dtype=self.type()) + else: + other_arr = constant_array(val, tdims[0] , tdims[1], tdims[2], tdims[3], self.type()) + del_other = True + else: + other_arr = val.arr + del_other = False + + out_arr = c_void_ptr_t(0) + inds = _get_indices(key) + + safe_call(backend.get().af_assign_gen(c_pointer(out_arr), + self.arr, c_dim_t(n_dims), inds.pointer, + other_arr)) + safe_call(backend.get().af_release_array(self.arr)) + if del_other: + safe_call(backend.get().af_release_array(other_arr)) + self.arr = out_arr + + except RuntimeError as e: + raise IndexError(str(e)) + + def _reorder(self): + """ + Returns a reordered array to help interoperate with row major formats. + """ + ndims = self.numdims() + if (ndims == 1): + return self + + rdims = tuple(reversed(range(ndims))) + tuple(range(ndims, 4)) + out = Array() + safe_call(backend.get().af_reorder(c_pointer(out.arr), self.arr, *rdims)) + return out + +
[docs] def to_ctype(self, row_major=False, return_shape=False): + """ + Return the data as a ctype C array after copying to host memory + + Parameters + ----------- + + row_major: optional: bool. default: False. + Specifies if a transpose needs to occur before copying to host memory. + + return_shape: optional: bool. default: False. + Specifies if the shape of the array needs to be returned. + + Returns + ------- + + If return_shape is False: + res: The ctypes array of the appropriate type and length. + else : + (res, dims): tuple of the ctypes array and the shape of the array + + """ + if (self.arr.value == 0): + raise RuntimeError("Can not call to_ctype on empty array") + + tmp = self._reorder() if (row_major) else self + + ctype_type = to_c_type[self.type()] * self.elements() + res = ctype_type() + + safe_call(backend.get().af_get_data_ptr(c_pointer(res), self.arr)) + if (return_shape): + return res, self.dims() + else: + return res
+ +
[docs] def to_array(self, row_major=False, return_shape=False): + """ + Return the data as array.array + + Parameters + ----------- + + row_major: optional: bool. default: False. + Specifies if a transpose needs to occur before copying to host memory. + + return_shape: optional: bool. default: False. + Specifies if the shape of the array needs to be returned. + + Returns + ------- + + If return_shape is False: + res: array.array of the appropriate type and length. + else : + (res, dims): array.array and the shape of the array + + """ + if (self.arr.value == 0): + raise RuntimeError("Can not call to_array on empty array") + + res = self.to_ctype(row_major, return_shape) + + host = __import__("array") + h_type = to_typecode[self.type()] + + if (return_shape): + return host.array(h_type, res[0]), res[1] + else: + return host.array(h_type, res)
+ +
[docs] def to_list(self, row_major=False): + """ + Return the data as list + + Parameters + ----------- + + row_major: optional: bool. default: False. + Specifies if a transpose needs to occur before copying to host memory. + + return_shape: optional: bool. default: False. + Specifies if the shape of the array needs to be returned. + + Returns + ------- + + If return_shape is False: + res: list of the appropriate type and length. + else : + (res, dims): list and the shape of the array + + """ + ct_array, shape = self.to_ctype(row_major, True) + return _ctype_to_lists(ct_array, len(shape) - 1, shape)
+ +
[docs] def scalar(self): + """ + Return the first element of the array + """ + + if (self.arr.value == 0): + raise RuntimeError("Can not call to_ctype on empty array") + + ctype_type = to_c_type[self.type()] + res = ctype_type() + safe_call(backend.get().af_get_scalar(c_pointer(res), self.arr)) + return res.value
+ + def __str__(self): + """ + Converts the arrayfire array to string showing its meta data and contents. + + Note + ---- + You can also use af.display(a, pres) to display the contents of the array with better precision. + """ + + if not _in_display_dims_limit(self.dims()): + return self._get_metadata_str() + + return self._get_metadata_str(dims=False) + self._as_str() + + def __repr__(self): + """ + Displays the meta data of the arrayfire array. + + Note + ---- + You can use af.display(a, pres) to display the contents of the array. + """ + + return self._get_metadata_str() + + def _get_metadata_str(self, dims=True): + return 'arrayfire.Array()\nType: {}\n{}' \ + .format(to_typename[self.type()], 'Dims: {}'.format(str(self.dims())) if dims else '') + + def _as_str(self): + arr_str = c_char_ptr_t(0) + be = backend.get() + safe_call(be.af_array_to_string(c_pointer(arr_str), "", self.arr, 4, True)) + py_str = to_str(arr_str) + safe_call(be.af_free_host(arr_str)) + return py_str + + def __array__(self): + """ + Constructs a numpy.array from arrayfire.Array + """ + import numpy as np + res = np.empty(self.dims(), dtype=np.dtype(to_typecode[self.type()]), order='F') + safe_call(backend.get().af_get_data_ptr(c_void_ptr_t(res.ctypes.data), self.arr)) + return res + +
[docs] def to_ndarray(self, output=None): + """ + Parameters + ----------- + output: optional: numpy. default: None + + Returns + ---------- + If output is None: Constructs a numpy.array from arrayfire.Array + If output is not None: copies content of af.array into numpy array. + + Note + ------ + + - An exception is thrown when output is not None and it is not contiguous. + - When output is None, The returned array is in fortran contiguous order. + """ + if output is None: + return self.__array__() + + if (output.dtype != to_typecode[self.type()]): + raise TypeError("Output is not the same type as the array") + + if (output.size != self.elements()): + raise RuntimeError("Output size does not match that of input") + + flags = output.flags + tmp = None + if flags['F_CONTIGUOUS']: + tmp = self + elif flags['C_CONTIGUOUS']: + tmp = self._reorder() + else: + raise RuntimeError("When output is not None, it must be contiguous") + + safe_call(backend.get().af_get_data_ptr(c_void_ptr_t(output.ctypes.data), tmp.arr)) + return output
+ +
[docs]def display(a, precision=4): + """ + Displays the contents of an array. + + Parameters + ---------- + a : af.Array + Multi dimensional arrayfire array + precision: int. optional. + Specifies the number of precision bits to display + """ + expr = inspect.stack()[1][-2] + name = "" + + try: + if (expr is not None): + st = expr[0].find('(') + 1 + en = expr[0].rfind(')') + name = expr[0][st:en] + except IndexError: + pass + + safe_call(backend.get().af_print_array_gen(name.encode('utf-8'), + a.arr, c_int_t(precision)))
+ +
[docs]def save_array(key, a, filename, append=False): + """ + Save an array to disk. + + Parameters + ---------- + key : str + A name / key associated with the array + + a : af.Array + The array to be stored to disk + + filename : str + Location of the data file. + + append : Boolean. optional. default: False. + If the file already exists, specifies if the data should be appended or overwritten. + + Returns + --------- + index : int + The index of the array stored in the file. + """ + index = c_int_t(-1) + safe_call(backend.get().af_save_array(c_pointer(index), + key.encode('utf-8'), + a.arr, + filename.encode('utf-8'), + append)) + return index.value
+ +
[docs]def read_array(filename, index=None, key=None): + """ + Read an array from disk. + + Parameters + ---------- + + filename : str + Location of the data file. + + index : int. Optional. Default: None. + - The index of the array stored in the file. + - If None, key is used. + + key : str. Optional. Default: None. + - A name / key associated with the array + - If None, index is used. + + Returns + --------- + """ + assert((index is not None) or (key is not None)) + out = Array() + if (index is not None): + safe_call(backend.get().af_read_array_index(c_pointer(out.arr), + filename.encode('utf-8'), + index)) + elif (key is not None): + safe_call(backend.get().af_read_array_key(c_pointer(out.arr), + filename.encode('utf-8'), + key.encode('utf-8'))) + + return out
+ +from .algorithm import (sum, count) +from .arith import cast +
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/base.html b/_modules/arrayfire/base.html new file mode 100644 index 000000000..599b7dd9e --- /dev/null +++ b/_modules/arrayfire/base.html @@ -0,0 +1,124 @@ + + + + + + + + arrayfire.base — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.base

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Implementation of BaseArray class.
+"""
+
+from .library import *
+from .util import *
+
+
[docs]class BaseArray(object): + """ + Base array class for arrayfire. For internal use only. + """ + def __init__(self): + self.arr = c_void_ptr_t(0)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/bcast.html b/_modules/arrayfire/bcast.html new file mode 100644 index 000000000..9dce8277d --- /dev/null +++ b/_modules/arrayfire/bcast.html @@ -0,0 +1,198 @@ + + + + + + + + arrayfire.bcast — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.bcast

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Function to perform broadcasting operations.
+"""
+
+class _bcast(object):
+    _flag = False
+    def get(self):
+        return _bcast._flag
+
+    def set(self, flag):
+        _bcast._flag = flag
+
+    def toggle(self):
+        _bcast._flag ^= True
+
+_bcast_var = _bcast()
+
+
[docs]def broadcast(func, *args): + """ + Function to perform broadcast operations. + + This function can be used directly or as an annotation in the following manner. + + Example + ------- + + Using broadcast as an annotation + + >>> import arrayfire as af + >>> @af.broadcast + ... def add(a, b): + ... return a + b + ... + >>> a = af.randu(2,3) + >>> b = af.randu(2,1) # b is a different size + >>> # Trying to add arrays of different sizes raises an exceptions + >>> c = add(a, b) # This call does not raise an exception because of the annotation + >>> af.display(a) + [2 3 1 1] + 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 + + >>> af.display(b) + [2 1 1 1] + 0.7269 + 0.7104 + + >>> af.display(c) + [2 3 1 1] + 1.1377 1.6787 1.1467 + 1.5328 0.8898 0.7185 + + Using broadcast as function + + >>> import arrayfire as af + >>> add = lambda a,b: a + b + >>> a = af.randu(2,3) + >>> b = af.randu(2,1) # b is a different size + >>> # Trying to add arrays of different sizes raises an exceptions + >>> c = af.broadcast(add, a, b) # This call does not raise an exception + >>> af.display(a) + [2 3 1 1] + 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 + + >>> af.display(b) + [2 1 1 1] + 0.7269 + 0.7104 + + >>> af.display(c) + [2 3 1 1] + 1.1377 1.6787 1.1467 + 1.5328 0.8898 0.7185 + + """ + + def wrapper(*func_args): + _bcast_var.toggle() + res = func(*func_args) + _bcast_var.toggle() + return res + + if len(args) == 0: + return wrapper + else: + return wrapper(*args)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/blas.html b/_modules/arrayfire/blas.html new file mode 100644 index 000000000..83faf9949 --- /dev/null +++ b/_modules/arrayfire/blas.html @@ -0,0 +1,412 @@ + + + + + + + + arrayfire.blas — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.blas

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+BLAS functions (matmul, dot, etc)
+"""
+
+from .library import *
+from .array import *
+
+
[docs]def matmul(lhs, rhs, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE): + """ + Generalized matrix multiplication for two matrices. + + Parameters + ---------- + + lhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + lhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `lhs`. + - af.MATPROP.TRANS - If `lhs` has to be transposed before multiplying. + - af.MATPROP.CTRANS - If `lhs` has to be hermitian transposed before multiplying. + + rhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `rhs`. + - af.MATPROP.TRANS - If `rhs` has to be transposed before multiplying. + - af.MATPROP.CTRANS - If `rhs` has to be hermitian transposed before multiplying. + + Returns + ------- + + out : af.Array + Output of the matrix multiplication on `lhs` and `rhs`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + out = Array() + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, + lhs_opts.value, rhs_opts.value)) + return out
+ +
[docs]def matmulTN(lhs, rhs): + """ + Matrix multiplication after transposing the first matrix. + + Parameters + ---------- + + lhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + Returns + ------- + + out : af.Array + Output of the matrix multiplication on `transpose(lhs)` and `rhs`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + out = Array() + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, + MATPROP.TRANS.value, MATPROP.NONE.value)) + return out
+ +
[docs]def matmulNT(lhs, rhs): + """ + Matrix multiplication after transposing the second matrix. + + Parameters + ---------- + + lhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + Returns + ------- + + out : af.Array + Output of the matrix multiplication on `lhs` and `transpose(rhs)`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + out = Array() + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, + MATPROP.NONE.value, MATPROP.TRANS.value)) + return out
+ +
[docs]def matmulTT(lhs, rhs): + """ + Matrix multiplication after transposing both inputs. + + Parameters + ---------- + + lhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + Returns + ------- + + out : af.Array + Output of the matrix multiplication on `transpose(lhs)` and `transpose(rhs)`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + out = Array() + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, + MATPROP.TRANS.value, MATPROP.TRANS.value)) + return out
+ +
[docs]def dot(lhs, rhs, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE, return_scalar = False): + """ + Dot product of two input vectors. + + Parameters + ---------- + + lhs : af.Array + A 1 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 1 dimensional, real or complex arrayfire array. + + lhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `lhs`. + - No other options are currently supported. + + rhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `rhs`. + - No other options are currently supported. + + return_scalar: optional: bool. default: False. + - When set to true, the input arrays are flattened and the output is a scalar + + Returns + ------- + + out : af.Array or scalar + Output of dot product of `lhs` and `rhs`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + if return_scalar: + real = c_double_t(0) + imag = c_double_t(0) + safe_call(backend.get().af_dot_all(c_pointer(real), c_pointer(imag), + lhs.arr, rhs.arr, lhs_opts.value, rhs_opts.value)) + real = real.value + imag = imag.value + return real if imag == 0 else real + imag * 1j + else: + out = Array() + safe_call(backend.get().af_dot(c_pointer(out.arr), lhs.arr, rhs.arr, + lhs_opts.value, rhs_opts.value)) + return out
+ +
[docs]def gemm(lhs, rhs, alpha=1.0, beta=0.0, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE, C=None): + """ + BLAS general matrix multiply (GEMM) of two af_array objects. + + This provides a general interface to the BLAS level 3 general matrix multiply (GEMM), which is generally defined as: + + C = alpha * opA(A) opB(B) + beta * C + + where alpha and beta are both scalars; A and B are the matrix multiply operands; + and opA and opB are noop (if AF_MAT_NONE) or transpose (if AF_MAT_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. + + Parameters + ---------- + + lhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + rhs : af.Array + A 2 dimensional, real or complex arrayfire array. + + alpha : scalar + + beta : scalar + + lhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `lhs`. + - af.MATPROP.TRANS - If `lhs` has to be transposed before multiplying. + - af.MATPROP.CTRANS - If `lhs` has to be hermitian transposed before multiplying. + + rhs_opts: optional: af.MATPROP. default: af.MATPROP.NONE. + Can be one of + - af.MATPROP.NONE - If no op should be done on `rhs`. + - af.MATPROP.TRANS - If `rhs` has to be transposed before multiplying. + - af.MATPROP.CTRANS - If `rhs` has to be hermitian transposed before multiplying. + + Returns + ------- + + out : af.Array + Output of the matrix multiplication on `lhs` and `rhs`. + + Note + ----- + + - The data types of `lhs` and `rhs` should be the same. + - Batches are not supported. + + """ + if C is None: + out = Array() + else: + out = C + + ltype = lhs.dtype() + + if ltype == Dtype.f32: + aptr = c_cast(c_pointer(c_float_t(alpha)),c_void_ptr_t) + bptr = c_cast(c_pointer(c_float_t(beta)), c_void_ptr_t) + elif ltype == Dtype.c32: + if isinstance(alpha, af_cfloat_t): + aptr = c_cast(c_pointer(alpha), c_void_ptr_t) + elif isinstance(alpha, tuple): + aptr = c_cast(c_pointer(af_cfloat_t(alpha[0], alpha[1])), c_void_ptr_t) + else: + aptr = c_cast(c_pointer(af_cfloat_t(alpha)), c_void_ptr_t) + + if isinstance(beta, af_cfloat_t): + bptr = c_cast(c_pointer(beta), c_void_ptr_t) + elif isinstance(beta, tuple): + bptr = c_cast(c_pointer(af_cfloat_t(beta[0], beta[1])), c_void_ptr_t) + else: + bptr = c_cast(c_pointer(af_cfloat_t(beta)), c_void_ptr_t) + + elif ltype == Dtype.f64: + aptr = c_cast(c_pointer(c_double_t(alpha)),c_void_ptr_t) + bptr = c_cast(c_pointer(c_double_t(beta)), c_void_ptr_t) + elif ltype == Dtype.c64: + if isinstance(alpha, af_cdouble_t): + aptr = c_cast(c_pointer(alpha), c_void_ptr_t) + elif isinstance(alpha, tuple): + aptr = c_cast(c_pointer(af_cdouble_t(alpha[0], alpha[1])), c_void_ptr_t) + else: + aptr = c_cast(c_pointer(af_cdouble_t(alpha)), c_void_ptr_t) + + if isinstance(beta, af_cdouble_t): + bptr = c_cast(c_pointer(beta), c_void_ptr_t) + elif isinstance(beta, tuple): + bptr = c_cast(c_pointer(af_cdouble_t(beta[0], beta[1])), c_void_ptr_t) + else: + bptr = c_cast(c_pointer(af_cdouble_t(beta)), c_void_ptr_t) + elif ltype == Dtype.f16: + raise TypeError("fp16 currently unsupported gemm() input type") + else: + raise TypeError("unsupported input type") + + + safe_call(backend.get().af_gemm(c_pointer(out.arr), + lhs_opts.value, rhs_opts.value, + aptr, lhs.arr, rhs.arr, bptr)) + return out
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/cuda.html b/_modules/arrayfire/cuda.html new file mode 100644 index 000000000..d91e8332c --- /dev/null +++ b/_modules/arrayfire/cuda.html @@ -0,0 +1,189 @@ + + + + + + + + arrayfire.cuda — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.cuda

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Functions specific to CUDA backend.
+
+This module provides interoperability with other CUDA libraries.
+"""
+
+
[docs]def get_stream(idx): + """ + Get the CUDA stream used for the device `idx` by ArrayFire. + + Parameters + ---------- + + idx : int. + Specifies the index of the device. + + Returns + ----------- + stream : integer denoting the stream id. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend as backend + + if (backend.name() != "cuda"): + raise RuntimeError("Invalid backend loaded") + + stream = c_void_ptr_t(0) + safe_call(backend.get().afcu_get_stream(c_pointer(stream), idx)) + return stream.value
+ +
[docs]def get_native_id(idx): + """ + Get native (unsorted) CUDA device ID + + Parameters + ---------- + + idx : int. + Specifies the (sorted) index of the device. + + Returns + ----------- + native_idx : integer denoting the native cuda id. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend as backend + + if (backend.name() != "cuda"): + raise RuntimeError("Invalid backend loaded") + + native = c_int_t(0) + safe_call(backend.get().afcu_get_native_id(c_pointer(native), idx)) + return native.value
+ +
[docs]def set_native_id(idx): + """ + Set native (unsorted) CUDA device ID + + Parameters + ---------- + + idx : int. + Specifies the (unsorted) native index of the device. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend as backend + + if (backend.name() != "cuda"): + raise RuntimeError("Invalid backend loaded") + + safe_call(backend.get().afcu_set_native_id(idx)) + return
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/data.html b/_modules/arrayfire/data.html new file mode 100644 index 000000000..b5d531fb1 --- /dev/null +++ b/_modules/arrayfire/data.html @@ -0,0 +1,1001 @@ + + + + + + + + arrayfire.data — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.data

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Functions to create and manipulate arrays.
+"""
+
+from sys import version_info
+from .library import *
+from .array import *
+from .util import *
+from .util import _is_number
+from .random import randu, randn, set_seed, get_seed
+
+
[docs]def constant(val, d0, d1=None, d2=None, d3=None, dtype=Dtype.f32): + """ + Create a multi dimensional array whose elements contain the same value. + + Parameters + ---------- + val : scalar. + Value of each element of the constant array. + + d0 : int. + Length of first dimension. + + d1 : optional: int. default: None. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + Returns + ------- + + out : af.Array + Multi dimensional array whose elements are of value `val`. + - If d1 is None, `out` is 1D of size (d0,). + - If d1 is not None and d2 is None, `out` is 2D of size (d0, d1). + - If d1 and d2 are not None and d3 is None, `out` is 3D of size (d0, d1, d2). + - If d1, d2, d3 are all not None, `out` is 4D of size (d0, d1, d2, d3). + """ + + out = Array() + out.arr = constant_array(val, d0, d1, d2, d3, dtype.value) + return out
+ +# Store builtin range function to be used later +_brange = range + +
[docs]def range(d0, d1=None, d2=None, d3=None, dim=0, dtype=Dtype.f32): + """ + Create a multi dimensional array using length of a dimension as range. + + Parameters + ---------- + val : scalar. + Value of each element of the constant array. + + d0 : int. + Length of first dimension. + + d1 : optional: int. default: None. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + dim : optional: int. default: 0. + The dimension along which the range is calculated. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + Returns + ------- + + out : af.Array + Multi dimensional array whose elements are along `dim` fall between [0 - self.dims[dim]-1] + - If d1 is None, `out` is 1D of size (d0,). + - If d1 is not None and d2 is None, `out` is 2D of size (d0, d1). + - If d1 and d2 are not None and d3 is None, `out` is 3D of size (d0, d1, d2). + - If d1, d2, d3 are all not None, `out` is 4D of size (d0, d1, d2, d3). + + + Examples + -------- + >>> import arrayfire as af + >>> a = af.range(3, 2) # dim is not specified, range is along first dimension. + >>> af.display(a) # The data ranges from [0 - 2] (3 elements along first dimension) + [3 2 1 1] + 0.0000 0.0000 + 1.0000 1.0000 + 2.0000 2.0000 + + >>> a = af.range(3, 2, dim=1) # dim is 1, range is along second dimension. + >>> af.display(a) # The data ranges from [0 - 1] (2 elements along second dimension) + [3 2 1 1] + 0.0000 1.0000 + 0.0000 1.0000 + 0.0000 1.0000 + """ + out = Array() + dims = dim4(d0, d1, d2, d3) + + safe_call(backend.get().af_range(c_pointer(out.arr), 4, c_pointer(dims), dim, dtype.value)) + return out
+ + +
[docs]def iota(d0, d1=None, d2=None, d3=None, dim=-1, tile_dims=None, dtype=Dtype.f32): + """ + Create a multi dimensional array using the number of elements in the array as the range. + + Parameters + ---------- + val : scalar. + Value of each element of the constant array. + + d0 : int. + Length of first dimension. + + d1 : optional: int. default: None. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + tile_dims : optional: tuple of ints. default: None. + The number of times the data is tiled. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + Returns + ------- + + out : af.Array + Multi dimensional array whose elements are along `dim` fall between [0 - self.elements() - 1]. + + Examples + -------- + >>> import arrayfire as af + >>> import arrayfire as af + >>> a = af.iota(3,3) # tile_dim is not specified, data is not tiled + >>> af.display(a) # the elements range from [0 - 8] (9 elements) + [3 3 1 1] + 0.0000 3.0000 6.0000 + 1.0000 4.0000 7.0000 + 2.0000 5.0000 8.0000 + + >>> b = af.iota(3,3,tile_dims(1,2)) # Asking to tile along second dimension. + >>> af.display(b) + [3 6 1 1] + 0.0000 3.0000 6.0000 0.0000 3.0000 6.0000 + 1.0000 4.0000 7.0000 1.0000 4.0000 7.0000 + 2.0000 5.0000 8.0000 2.0000 5.0000 8.0000 + """ + out = Array() + dims = dim4(d0, d1, d2, d3) + td=[1]*4 + + if tile_dims is not None: + for i in _brange(len(tile_dims)): + td[i] = tile_dims[i] + + tdims = dim4(td[0], td[1], td[2], td[3]) + + safe_call(backend.get().af_iota(c_pointer(out.arr), 4, c_pointer(dims), + 4, c_pointer(tdims), dtype.value)) + return out
+ +
[docs]def identity(d0, d1, d2=None, d3=None, dtype=Dtype.f32): + """ + Create an identity matrix or batch of identity matrices. + + Parameters + ---------- + d0 : int. + Length of first dimension. + + d1 : int. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + Returns + ------- + + out : af.Array + Multi dimensional array whose first two dimensions form a identity matrix. + - If d2 is None, `out` is 2D of size (d0, d1). + - If d2 is not None and d3 is None, `out` is 3D of size (d0, d1, d2). + - If d2, d3 are not None, `out` is 4D of size (d0, d1, d2, d3). + """ + + out = Array() + dims = dim4(d0, d1, d2, d3) + + safe_call(backend.get().af_identity(c_pointer(out.arr), 4, c_pointer(dims), dtype.value)) + return out
+ +
[docs]def diag(a, num=0, extract=True): + """ + Create a diagonal matrix or Extract the diagonal from a matrix. + + Parameters + ---------- + a : af.Array. + 1 dimensional or 2 dimensional arrayfire array. + + num : optional: int. default: 0. + The index of the diagonal. + - num == 0 signifies the diagonal. + - num > 0 signifies super diagonals. + - num < 0 signifies sub diagonals. + + extract : optional: bool. default: True. + - If True , diagonal is extracted. `a` has to be 2D. + - If False, diagonal matrix is created. `a` has to be 1D. + + Returns + ------- + + out : af.Array + - if extract is True, `out` contains the num'th diagonal from `a`. + - if extract is False, `out` contains `a` as the num'th diagonal. + """ + out = Array() + if extract: + safe_call(backend.get().af_diag_extract(c_pointer(out.arr), a.arr, c_int_t(num))) + else: + safe_call(backend.get().af_diag_create(c_pointer(out.arr), a.arr, c_int_t(num))) + return out
+ +
[docs]def join(dim, first, second, third=None, fourth=None): + """ + Join two or more arrayfire arrays along a specified dimension. + + Parameters + ---------- + + dim: int. + Dimension along which the join occurs. + + first : af.Array. + Multi dimensional arrayfire array. + + second : af.Array. + Multi dimensional arrayfire array. + + third : optional: af.Array. default: None. + Multi dimensional arrayfire array. + + fourth : optional: af.Array. default: None. + Multi dimensional arrayfire array. + + Returns + ------- + + out : af.Array + An array containing the input arrays joined along the specified dimension. + + Examples + --------- + + >>> import arrayfire as af + >>> a = af.randu(2, 3) + >>> b = af.randu(2, 3) + >>> c = af.join(0, a, b) + >>> d = af.join(1, a, b) + >>> af.display(a) + [2 3 1 1] + 0.9508 0.2591 0.7928 + 0.5367 0.8359 0.8719 + + >>> af.display(b) + [2 3 1 1] + 0.3266 0.6009 0.2442 + 0.6275 0.0495 0.6591 + + >>> af.display(c) + [4 3 1 1] + 0.9508 0.2591 0.7928 + 0.5367 0.8359 0.8719 + 0.3266 0.6009 0.2442 + 0.6275 0.0495 0.6591 + + >>> af.display(d) + [2 6 1 1] + 0.9508 0.2591 0.7928 0.3266 0.6009 0.2442 + 0.5367 0.8359 0.8719 0.6275 0.0495 0.6591 + """ + out = Array() + if (third is None and fourth is None): + safe_call(backend.get().af_join(c_pointer(out.arr), dim, first.arr, second.arr)) + else: + c_void_p_4 = c_void_ptr_t * 4 + c_array_vec = c_void_p_4(first.arr, second.arr, 0, 0) + num = 2 + if third is not None: + c_array_vec[num] = third.arr + num+=1 + if fourth is not None: + c_array_vec[num] = fourth.arr + num+=1 + + safe_call(backend.get().af_join_many(c_pointer(out.arr), dim, num, c_pointer(c_array_vec))) + return out
+ + +
[docs]def tile(a, d0, d1=1, d2=1, d3=1): + """ + Tile an array along specified dimensions. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + d0: int. + The number of times `a` has to be tiled along first dimension. + + d1: optional: int. default: 1. + The number of times `a` has to be tiled along second dimension. + + d2: optional: int. default: 1. + The number of times `a` has to be tiled along third dimension. + + d3: optional: int. default: 1. + The number of times `a` has to be tiled along fourth dimension. + + Returns + ------- + + out : af.Array + An array containing the input after tiling the the specified number of times. + + Examples + --------- + + >>> import arrayfire as af + >>> a = af.randu(2, 3) + >>> b = af.tile(a, 2) + >>> c = af.tile(a, 1, 2) + >>> d = af.tile(a, 2, 2) + >>> af.display(a) + [2 3 1 1] + 0.9508 0.2591 0.7928 + 0.5367 0.8359 0.8719 + + >>> af.display(b) + [4 3 1 1] + 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 + 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 + + >>> af.display(c) + [2 6 1 1] + 0.4107 0.9518 0.4198 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 0.8224 0.1794 0.0081 + + >>> af.display(d) + [4 6 1 1] + 0.4107 0.9518 0.4198 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 0.8224 0.1794 0.0081 + 0.4107 0.9518 0.4198 0.4107 0.9518 0.4198 + 0.8224 0.1794 0.0081 0.8224 0.1794 0.0081 + """ + out = Array() + safe_call(backend.get().af_tile(c_pointer(out.arr), a.arr, d0, d1, d2, d3)) + return out
+ +
[docs]def reorder(a, d0=1, d1=0, d2=2, d3=3): + """ + Reorder the dimensions of the input. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + d0: optional: int. default: 1. + The location of the first dimension in the output. + + d1: optional: int. default: 0. + The location of the second dimension in the output. + + d2: optional: int. default: 2. + The location of the third dimension in the output. + + d3: optional: int. default: 3. + The location of the fourth dimension in the output. + + Returns + ------- + + out : af.Array + - An array containing the input aftern reordering its dimensions. + + Note + ------ + - `af.reorder(a, 1, 0)` is the same as `transpose(a)` + + Examples + -------- + >>> import arrayfire as af + >>> a = af.randu(5, 5, 3) + >>> af.display(a) + [5 5 3 1] + 0.4107 0.0081 0.6600 0.1046 0.8395 + 0.8224 0.3775 0.0764 0.8827 0.1933 + 0.9518 0.3027 0.0901 0.1647 0.7270 + 0.1794 0.6456 0.5933 0.8060 0.0322 + 0.4198 0.5591 0.1098 0.5938 0.0012 + + 0.8703 0.9250 0.4387 0.6530 0.4224 + 0.5259 0.3063 0.3784 0.5476 0.5293 + 0.1443 0.9313 0.4002 0.8577 0.0212 + 0.3253 0.8684 0.4390 0.8370 0.1103 + 0.5081 0.6592 0.4718 0.0618 0.4420 + + 0.8355 0.6767 0.1033 0.9426 0.9276 + 0.4878 0.6742 0.2119 0.4817 0.8662 + 0.2055 0.4523 0.5955 0.9097 0.3578 + 0.1794 0.1236 0.3745 0.6821 0.6263 + 0.5606 0.7924 0.9165 0.6056 0.9747 + + + >>> b = af.reorder(a, 2, 0, 1) + >>> af.display(b) + [3 5 5 1] + 0.4107 0.8224 0.9518 0.1794 0.4198 + 0.8703 0.5259 0.1443 0.3253 0.5081 + 0.8355 0.4878 0.2055 0.1794 0.5606 + + 0.0081 0.3775 0.3027 0.6456 0.5591 + 0.9250 0.3063 0.9313 0.8684 0.6592 + 0.6767 0.6742 0.4523 0.1236 0.7924 + + 0.6600 0.0764 0.0901 0.5933 0.1098 + 0.4387 0.3784 0.4002 0.4390 0.4718 + 0.1033 0.2119 0.5955 0.3745 0.9165 + + 0.1046 0.8827 0.1647 0.8060 0.5938 + 0.6530 0.5476 0.8577 0.8370 0.0618 + 0.9426 0.4817 0.9097 0.6821 0.6056 + + 0.8395 0.1933 0.7270 0.0322 0.0012 + 0.4224 0.5293 0.0212 0.1103 0.4420 + 0.9276 0.8662 0.3578 0.6263 0.9747 + """ + out = Array() + safe_call(backend.get().af_reorder(c_pointer(out.arr), a.arr, d0, d1, d2, d3)) + return out
+ +
[docs]def shift(a, d0, d1=0, d2=0, d3=0): + """ + Shift the input along each dimension. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + d0: int. + The amount of shift along first dimension. + + d1: optional: int. default: 0. + The amount of shift along second dimension. + + d2: optional: int. default: 0. + The amount of shift along third dimension. + + d3: optional: int. default: 0. + The amount of shift along fourth dimension. + + Returns + ------- + + out : af.Array + - An array the same shape as `a` after shifting it by the specified amounts. + + Examples + -------- + >>> import arrayfire as af + >>> a = af.randu(3, 3) + >>> b = af.shift(a, 2) + >>> c = af.shift(a, 1, -1) + >>> af.display(a) + [3 3 1 1] + 0.7269 0.3569 0.3341 + 0.7104 0.1437 0.0899 + 0.5201 0.4563 0.5363 + + >>> af.display(b) + [3 3 1 1] + 0.7104 0.1437 0.0899 + 0.5201 0.4563 0.5363 + 0.7269 0.3569 0.3341 + + >>> af.display(c) + [3 3 1 1] + 0.4563 0.5363 0.5201 + 0.3569 0.3341 0.7269 + 0.1437 0.0899 0.7104 + """ + out = Array() + safe_call(backend.get().af_shift(c_pointer(out.arr), a.arr, d0, d1, d2, d3)) + return out
+ +
[docs]def moddims(a, d0, d1=1, d2=1, d3=1): + """ + Modify the shape of the array without changing the data layout. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + d0: int. + The first dimension of output. + + d1: optional: int. default: 1. + The second dimension of output. + + d2: optional: int. default: 1. + The third dimension of output. + + d3: optional: int. default: 1. + The fourth dimension of output. + + Returns + ------- + + out : af.Array + - An containing the same data as `a` with the specified shape. + - The number of elements in `a` must match `d0 x d1 x d2 x d3`. + """ + out = Array() + dims = dim4(d0, d1, d2, d3) + safe_call(backend.get().af_moddims(c_pointer(out.arr), a.arr, 4, c_pointer(dims))) + return out
+ +
[docs]def flat(a): + """ + Flatten the input array. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + Returns + ------- + + out : af.Array + - 1 dimensional array containing all the elements from `a`. + """ + out = Array() + safe_call(backend.get().af_flat(c_pointer(out.arr), a.arr)) + return out
+ +
[docs]def flip(a, dim=0): + """ + Flip an array along a dimension. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + dim : optional: int. default: 0. + The dimension along which the flip is performed. + + Returns + ------- + + out : af.Array + The output after flipping `a` along `dim`. + + Examples + --------- + + >>> import arrayfire as af + >>> a = af.randu(3, 3) + >>> af.display(a) + [3 3 1 1] + 0.7269 0.3569 0.3341 + 0.7104 0.1437 0.0899 + 0.5201 0.4563 0.5363 + + >>> af.display(b) + [3 3 1 1] + 0.5201 0.4563 0.5363 + 0.7104 0.1437 0.0899 + 0.7269 0.3569 0.3341 + + >>> af.display(c) + [3 3 1 1] + 0.3341 0.3569 0.7269 + 0.0899 0.1437 0.7104 + 0.5363 0.4563 0.5201 + + """ + out = Array() + safe_call(backend.get().af_flip(c_pointer(out.arr), a.arr, c_int_t(dim))) + return out
+ +
[docs]def lower(a, is_unit_diag=False): + """ + Extract the lower triangular matrix from the input. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + is_unit_diag: optional: bool. default: False. + Flag specifying if the diagonal elements are 1. + + Returns + ------- + + out : af.Array + An array containing the lower triangular elements from `a`. + """ + out = Array() + safe_call(backend.get().af_lower(c_pointer(out.arr), a.arr, is_unit_diag)) + return out
+ +
[docs]def upper(a, is_unit_diag=False): + """ + Extract the upper triangular matrix from the input. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + is_unit_diag: optional: bool. default: False. + Flag specifying if the diagonal elements are 1. + + Returns + ------- + + out : af.Array + An array containing the upper triangular elements from `a`. + """ + out = Array() + safe_call(backend.get().af_upper(c_pointer(out.arr), a.arr, is_unit_diag)) + return out
+ +
[docs]def select(cond, lhs, rhs): + """ + Select elements from one of two arrays based on condition. + + Parameters + ---------- + + cond : af.Array + Conditional array + + lhs : af.Array or scalar + numerical array whose elements are picked when conditional element is True + + rhs : af.Array or scalar + numerical array whose elements are picked when conditional element is False + + Returns + -------- + + out: af.Array + An array containing elements from `lhs` when `cond` is True and `rhs` when False. + + Examples + --------- + + >>> import arrayfire as af + >>> a = af.randu(3,3) + >>> b = af.randu(3,3) + >>> cond = a > b + >>> res = af.select(cond, a, b) + + >>> af.display(a) + [3 3 1 1] + 0.4107 0.1794 0.3775 + 0.8224 0.4198 0.3027 + 0.9518 0.0081 0.6456 + + >>> af.display(b) + [3 3 1 1] + 0.7269 0.3569 0.3341 + 0.7104 0.1437 0.0899 + 0.5201 0.4563 0.5363 + + >>> af.display(res) + [3 3 1 1] + 0.7269 0.3569 0.3775 + 0.8224 0.4198 0.3027 + 0.9518 0.4563 0.6456 + """ + out = Array() + + is_left_array = isinstance(lhs, Array) + is_right_array = isinstance(rhs, Array) + + if not (is_left_array or is_right_array): + raise TypeError("Atleast one input needs to be of type arrayfire.array") + + elif (is_left_array and is_right_array): + safe_call(backend.get().af_select(c_pointer(out.arr), cond.arr, lhs.arr, rhs.arr)) + + elif (_is_number(rhs)): + safe_call(backend.get().af_select_scalar_r(c_pointer(out.arr), cond.arr, lhs.arr, c_double_t(rhs))) + else: + safe_call(backend.get().af_select_scalar_l(c_pointer(out.arr), cond.arr, c_double_t(lhs), rhs.arr)) + + return out
+ +
[docs]def replace(lhs, cond, rhs): + """ + Select elements from one of two arrays based on condition. + + Parameters + ---------- + + lhs : af.Array or scalar + numerical array whose elements are replaced with `rhs` when conditional element is False + + cond : af.Array + Conditional array + + rhs : af.Array or scalar + numerical array whose elements are picked when conditional element is False + + Examples + --------- + >>> import arrayfire as af + >>> a = af.randu(3,3) + >>> af.display(a) + [3 3 1 1] + 0.4107 0.1794 0.3775 + 0.8224 0.4198 0.3027 + 0.9518 0.0081 0.6456 + + >>> cond = (a >= 0.25) & (a <= 0.75) + >>> af.display(cond) + [3 3 1 1] + 1 0 1 + 0 1 1 + 0 0 1 + + >>> af.replace(a, cond, 0.3333) + >>> af.display(a) + [3 3 1 1] + 0.3333 0.1794 0.3333 + 0.8224 0.3333 0.3333 + 0.9518 0.0081 0.3333 + + """ + is_right_array = isinstance(rhs, Array) + + if (is_right_array): + safe_call(backend.get().af_replace(lhs.arr, cond.arr, rhs.arr)) + else: + safe_call(backend.get().af_replace_scalar(lhs.arr, cond.arr, c_double_t(rhs)))
+ +
[docs]def pad(a, beginPadding, endPadding, padFillType = PAD.ZERO): + """ + Pad an array + + This function will pad an array with the specified border size. + Newly padded values can be filled in several different ways. + + Parameters + ---------- + + a: af.Array + A multi dimensional input arrayfire array. + + beginPadding: tuple of ints. default: (0, 0, 0, 0). + + endPadding: tuple of ints. default: (0, 0, 0, 0). + + padFillType: optional af.PAD default: af.PAD.ZERO + specifies type of values to fill padded border with + + Returns + ------- + output: af.Array + A padded array + + Examples + --------- + >>> import arrayfire as af + >>> a = af.randu(3,3) + >>> af.display(a) + [3 3 1 1] + 0.4107 0.1794 0.3775 + 0.8224 0.4198 0.3027 + 0.9518 0.0081 0.6456 + + >>> padded = af.pad(a, (1, 1), (1, 1), af.ZERO) + >>> af.display(padded) + [5 5 1 1] + 0.0000 0.0000 0.0000 0.0000 0.0000 + 0.0000 0.4107 0.1794 0.3775 0.0000 + 0.0000 0.8224 0.4198 0.3027 0.0000 + 0.0000 0.9518 0.0081 0.6456 0.0000 + 0.0000 0.0000 0.0000 0.0000 0.0000 + """ + out = Array() + begin_dims = dim4(beginPadding[0], beginPadding[1], beginPadding[2], beginPadding[3]) + end_dims = dim4(endPadding[0], endPadding[1], endPadding[2], endPadding[3]) + + safe_call(backend.get().af_pad(c_pointer(out.arr), a.arr, 4, c_pointer(begin_dims), 4, c_pointer(end_dims), padFillType.value)) + return out
+ + +
[docs]def lookup(a, idx, dim=0): + """ + Lookup the values of input array based on index. + + Parameters + ---------- + + a : af.Array. + Multi dimensional array. + + idx : is lookup indices + + dim : optional: int. default: 0. + Specifies the dimension for indexing + + Returns + ------- + + out : af.Array + An array containing values at locations specified by 'idx' + + Examples + --------- + + >>> import arrayfire as af + >>> arr = af.Array([1,0,3,4,5,6], (2,3)) + >>> af.display(arr) + [2 3 1 1] + 1.0000 3.0000 5.0000 + 0.0000 4.0000 6.0000 + + >>> idx = af.array([0, 2]) + >>> af.lookup(arr, idx, 1) + [2 2 1 1] + 1.0000 5.0000 + 0.0000 6.0000 + + >>> idx = af.array([0]) + >>> af.lookup(arr, idx, 0) + [2 1 1 1] + 0.0000 + 2.0000 + """ + out = Array() + safe_call(backend.get().af_lookup(c_pointer(out.arr), a.arr, idx.arr, c_int_t(dim))) + return out
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/device.html b/_modules/arrayfire/device.html new file mode 100644 index 000000000..e3cf88242 --- /dev/null +++ b/_modules/arrayfire/device.html @@ -0,0 +1,580 @@ + + + + + + + + arrayfire.device — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.device

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+"""
+Functions to handle the available devices in the backend.
+"""
+
+from .library import *
+from .util import (safe_call, to_str, get_version)
+
+
[docs]def init(): + """ + Note + ----- + This function may need to be called when interoperating with other libraries + """ + safe_call(backend.get().af_init())
+ +
[docs]def info(): + """ + Displays the information about the following: + - ArrayFire build and version number. + - The number of devices available. + - The names of the devices. + - The current device being used. + """ + safe_call(backend.get().af_info())
+ +
[docs]def device_info(): + """ + Returns a map with the following fields: + - 'device': Name of the current device. + - 'backend': The current backend being used. + - 'toolkit': The toolkit version for the backend. + - 'compute': The compute version of the device. + """ + c_char_256 = c_char_t * 256 + device_name = c_char_256() + backend_name = c_char_256() + toolkit = c_char_256() + compute = c_char_256() + + safe_call(backend.get().af_device_info(c_pointer(device_name), c_pointer(backend_name), + c_pointer(toolkit), c_pointer(compute))) + dev_info = {} + dev_info['device'] = to_str(device_name) + dev_info['backend'] = to_str(backend_name) + dev_info['toolkit'] = to_str(toolkit) + dev_info['compute'] = to_str(compute) + + return dev_info
+ +
[docs]def get_device_count(): + """ + Returns the number of devices available. + """ + c_num = c_int_t(0) + safe_call(backend.get().af_get_device_count(c_pointer(c_num))) + return c_num.value
+ +
[docs]def get_device(): + """ + Returns the id of the current device. + """ + c_dev = c_int_t(0) + safe_call(backend.get().af_get_device(c_pointer(c_dev))) + return c_dev.value
+ +
[docs]def set_device(num): + """ + Change the active device to the specified id. + + Parameters + ----------- + num: int. + id of the desired device. + """ + safe_call(backend.get().af_set_device(num))
+ +
[docs]def info_str(verbose = False): + """ + Returns information about the following as a string: + - ArrayFire version number. + - The number of devices available. + - The names of the devices. + - The current device being used. + """ + import platform + res_str = 'ArrayFire' + + major, minor, patch = get_version() + dev_info = device_info() + backend_str = dev_info['backend'] + + res_str += ' v' + str(major) + '.' + str(minor) + '.' + str(patch) + res_str += ' (' + backend_str + ' ' + platform.architecture()[0] + ')\n' + + num_devices = get_device_count() + curr_device_id = get_device() + + for n in range(num_devices): + # To suppress warnings on CPU + if (n != curr_device_id): + set_device(n) + + if (n == curr_device_id): + res_str += '[%d] ' % n + else: + res_str += '-%d- ' % n + + dev_info = device_info() + + if (backend_str.lower() == 'opencl'): + res_str += dev_info['toolkit'] + + res_str += ': ' + dev_info['device'] + + if (backend_str.lower() != 'cpu'): + res_str += ' (Compute ' + dev_info['compute'] + ')' + + res_str += '\n' + + # To suppress warnings on CPU + if (curr_device_id != get_device()): + set_device(curr_device_id) + + return res_str
+ +
[docs]def is_dbl_supported(device=None): + """ + Check if double precision is supported on specified device. + + Parameters + ----------- + device: optional: int. default: None. + id of the desired device. + + Returns + -------- + - True if double precision supported. + - False if double precision not supported. + """ + dev = device if device is not None else get_device() + res = c_bool_t(False) + safe_call(backend.get().af_get_dbl_support(c_pointer(res), dev)) + return res.value
+ +
[docs]def is_half_supported(device=None): + """ + Check if half precision is supported on specified device. + + Parameters + ----------- + device: optional: int. default: None. + id of the desired device. + + Returns + -------- + - True if half precision supported. + - False if half precision not supported. + """ + dev = device if device is not None else get_device() + res = c_bool_t(False) + safe_call(backend.get().af_get_half_support(c_pointer(res), dev)) + return res.value
+ +
[docs]def sync(device=None): + """ + Block until all the functions on the device have completed execution. + + Parameters + ----------- + device: optional: int. default: None. + id of the desired device. + """ + dev = device if device is not None else get_device() + safe_call(backend.get().af_sync(dev))
+ +def __eval(*args): + nargs = len(args) + if (nargs == 1): + safe_call(backend.get().af_eval(args[0].arr)) + else: + c_void_p_n = c_void_ptr_t * nargs + arrs = c_void_p_n() + for n in range(nargs): + arrs[n] = args[n].arr + safe_call(backend.get().af_eval_multiple(c_int_t(nargs), c_pointer(arrs))) + return + +
[docs]def eval(*args): + """ + Evaluate one or more inputs together + + Parameters + ----------- + args : arguments to be evaluated + + Note + ----- + + All the input arrays to this function should be of the same size. + + Examples + -------- + + >>> a = af.constant(1, 3, 3) + >>> b = af.constant(2, 3, 3) + >>> c = a + b + >>> d = a - b + >>> af.eval(c, d) # A single kernel is launched here + >>> c + arrayfire.Array() + Type: float + [3 3 1 1] + 3.0000 3.0000 3.0000 + 3.0000 3.0000 3.0000 + 3.0000 3.0000 3.0000 + + >>> d + arrayfire.Array() + Type: float + [3 3 1 1] + -1.0000 -1.0000 -1.0000 + -1.0000 -1.0000 -1.0000 + -1.0000 -1.0000 -1.0000 + """ + for arg in args: + if not isinstance(arg, Array): + raise RuntimeError("All inputs to eval must be of type arrayfire.Array") + + __eval(*args)
+ +
[docs]def set_manual_eval_flag(flag): + """ + Tells the backend JIT engine to disable heuristics for determining when to evaluate a JIT tree. + + Parameters + ---------- + + flag : optional: bool. + - Specifies if the heuristic evaluation of the JIT tree needs to be disabled. + + Note + ---- + This does not affect the evaluation that occurs when a non JIT function forces the evaluation. + """ + safe_call(backend.get().af_set_manual_eval_flag(flag))
+ +
[docs]def get_manual_eval_flag(): + """ + Query the backend JIT engine to see if the user disabled heuristic evaluation of the JIT tree. + + Note + ---- + This does not affect the evaluation that occurs when a non JIT function forces the evaluation. + """ + res = c_bool_t(False) + safe_call(backend.get().af_get_manual_eval_flag(c_pointer(res))) + return res.value
+ +
[docs]def device_mem_info(): + """ + Returns a map with the following fields: + - 'alloc': Contains the map of the following + - 'buffers' : Total number of buffers allocated by memory manager. + - 'bytes' : Total number of bytes allocated by memory manager. + - 'lock': Contains the map of the following + - 'buffers' : Total number of buffers currently in scope. + - 'bytes' : Total number of bytes currently in scope. + + Note + ----- + ArrayFire does not free memory when array goes out of scope. The memory is marked for reuse. + - The difference between alloc buffers and lock buffers equals the number of free buffers. + - The difference between alloc bytes and lock bytes equals the number of free bytes. + + """ + alloc_bytes = c_size_t(0) + alloc_buffers = c_size_t(0) + lock_bytes = c_size_t(0) + lock_buffers = c_size_t(0) + safe_call(backend.get().af_device_mem_info(c_pointer(alloc_bytes), c_pointer(alloc_buffers), + c_pointer(lock_bytes), c_pointer(lock_buffers))) + mem_info = {} + mem_info['alloc'] = {'buffers' : alloc_buffers.value, 'bytes' : alloc_bytes.value} + mem_info['lock'] = {'buffers' : lock_buffers.value, 'bytes' : lock_bytes.value} + return mem_info
+ + + +
[docs]def device_gc(): + """ + Ask the garbage collector to free all unlocked memory + """ + safe_call(backend.get().af_device_gc())
+ +
[docs]def get_device_ptr(a): + """ + Get the raw device pointer of an array + + Parameters + ---------- + a: af.Array + - A multi dimensional arrayfire array. + + Returns + ------- + - internal device pointer held by a + + Note + ----- + - The device pointer of `a` is not freed by memory manager until `unlock_device_ptr()` is called. + - This function enables the user to interoperate arrayfire with other CUDA/OpenCL/C libraries. + + """ + ptr = c_void_ptr_t(0) + safe_call(backend.get().af_get_device_ptr(c_pointer(ptr), a.arr)) + return ptr
+ +
[docs]def lock_device_ptr(a): + """ + This functions is deprecated. Please use lock_array instead. + """ + import warnings + warnings.warn("This function is deprecated. Use lock_array instead.", DeprecationWarning) + lock_array(a)
+ +
[docs]def lock_array(a): + """ + Ask arrayfire to not perform garbage collection on raw data held by an array. + + Parameters + ---------- + a: af.Array + - A multi dimensional arrayfire array. + + Note + ----- + - The device pointer of `a` is not freed by memory manager until `unlock_array()` is called. + """ + safe_call(backend.get().af_lock_array(a.arr))
+ +
[docs]def is_locked_array(a): + """ + Check if the input array is locked by the user. + + Parameters + ---------- + a: af.Array + - A multi dimensional arrayfire array. + + Returns + ----------- + A bool specifying if the input array is locked. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_locked_array(c_pointer(res), a.arr)) + return res.value
+ +
[docs]def unlock_device_ptr(a): + """ + This functions is deprecated. Please use unlock_array instead. + """ + import warnings + warnings.warn("This function is deprecated. Use unlock_array instead.", DeprecationWarning) + unlock_array(a)
+ +
[docs]def unlock_array(a): + """ + Tell arrayfire to resume garbage collection on raw data held by an array. + + Parameters + ---------- + a: af.Array + - A multi dimensional arrayfire array. + + """ + safe_call(backend.get().af_unlock_array(a.arr))
+ +
[docs]def alloc_device(num_bytes): + """ + Allocate a buffer on the device with specified number of bytes. + """ + ptr = c_void_ptr_t(0) + c_num_bytes = c_dim_t(num_bytes) + safe_call(backend.get().af_alloc_device(c_pointer(ptr), c_num_bytes)) + return ptr.value
+ +
[docs]def alloc_host(num_bytes): + """ + Allocate a buffer on the host with specified number of bytes. + """ + ptr = c_void_ptr_t(0) + c_num_bytes = c_dim_t(num_bytes) + safe_call(backend.get().af_alloc_host(c_pointer(ptr), c_num_bytes)) + return ptr.value
+ +
[docs]def alloc_pinned(num_bytes): + """ + Allocate a buffer on the host using pinned memory with specified number of bytes. + """ + ptr = c_void_ptr_t(0) + c_num_bytes = c_dim_t(num_bytes) + safe_call(backend.get().af_alloc_pinned(c_pointer(ptr), c_num_bytes)) + return ptr.value
+ +
[docs]def free_device(ptr): + """ + Free the device memory allocated by alloc_device + """ + cptr = c_void_ptr_t(ptr) + safe_call(backend.get().af_free_device(cptr))
+ +
[docs]def free_host(ptr): + """ + Free the host memory allocated by alloc_host + """ + cptr = c_void_ptr_t(ptr) + safe_call(backend.get().af_free_host(cptr))
+ +
[docs]def free_pinned(ptr): + """ + Free the pinned memory allocated by alloc_pinned + """ + cptr = c_void_ptr_t(ptr) + safe_call(backend.get().af_free_pinned(cptr))
+ +from .array import Array +
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/features.html b/_modules/arrayfire/features.html new file mode 100644 index 000000000..cd6ad932d --- /dev/null +++ b/_modules/arrayfire/features.html @@ -0,0 +1,191 @@ + + + + + + + + arrayfire.features — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.features

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Features class used for Computer Vision algorithms.
+"""
+
+from .library import *
+from .array import *
+import numbers
+
+
[docs]class Features(object): + """ + A container class used for various feature detectors. + + Parameters + ---------- + + num: optional: int. default: 0. + Specifies the number of features. + """ + + def __init__(self, num=0): + self.feat = c_void_ptr_t(0) + if num is not None: + assert(isinstance(num, numbers.Number)) + safe_call(backend.get().af_create_features(c_pointer(self.feat), c_dim_t(num))) + + def __del__(self): + """ + Release features' memory + """ + if self.feat: + backend.get().af_release_features(self.feat) + self.feat = None + +
[docs] def num_features(self): + """ + Returns the number of features detected. + """ + num = c_dim_t(0) + safe_call(backend.get().af_get_features_num(c_pointer(num), self.feat)) + return num
+ +
[docs] def get_xpos(self): + """ + Returns the x-positions of the features detected. + """ + out = Array() + safe_call(backend.get().af_get_features_xpos(c_pointer(out.arr), self.feat)) + return out
+ +
[docs] def get_ypos(self): + """ + Returns the y-positions of the features detected. + """ + out = Array() + safe_call(backend.get().af_get_features_ypos(c_pointer(out.arr), self.feat)) + return out
+ +
[docs] def get_score(self): + """ + Returns the scores of the features detected. + """ + out = Array() + safe_call(backend.get().af_get_features_score(c_pointer(out.arr), self.feat)) + return out
+ +
[docs] def get_orientation(self): + """ + Returns the orientations of the features detected. + """ + out = Array() + safe_call(backend.get().af_get_features_orientation(c_pointer(out.arr), self.feat)) + return out
+ +
[docs] def get_size(self): + """ + Returns the sizes of the features detected. + """ + out = Array() + safe_call(backend.get().af_get_features_size(c_pointer(out.arr), self.feat)) + return out
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/graphics.html b/_modules/arrayfire/graphics.html new file mode 100644 index 000000000..453767884 --- /dev/null +++ b/_modules/arrayfire/graphics.html @@ -0,0 +1,653 @@ + + + + + + + + arrayfire.graphics — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.graphics

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Graphics functions (plot, image, etc).
+"""
+
+from .library import *
+from .array import *
+from .util import _is_number
+
+class _Cell(ct.Structure):
+    _fields_ = [("row", c_int_t),
+                ("col", c_int_t),
+                ("title", c_char_ptr_t),
+                ("cmap", c_int_t)]
+
+    def __init__(self, r, c, title, cmap):
+        self.row = r
+        self.col = c
+        self.title = title if title is not None else c_char_ptr_t()
+        self.cmap = cmap.value
+
+
[docs]class Window(object): + """ + Class to create the Window object. + + Parameters + ---------- + + width: optional: int. default: 1280. + - Specifies the width of the window in pixels. + + height: optional: int. default: 720. + - Specifies the height of the window in pixels. + + title: optional: str. default: "ArrayFire". + - Specifies the title used for the window. + + """ + + def __init__(self, width=1280, height=720, title="ArrayFire"): + self._r = -1 + self._c = -1 + self._wnd = c_void_ptr_t(0) + self._cmap = COLORMAP.DEFAULT + + _width = 1280 if width is None else width + _height = 720 if height is None else height + _title = "ArrayFire" if title is None else title + + _title = _title.encode("ascii") + + safe_call(backend.get().af_create_window(c_pointer(self._wnd), + c_int_t(_width), c_int_t(_height), + c_char_ptr_t(_title))) + + def __del__(self): + """ + Destroys the window when going out of scope. + """ + safe_call(backend.get().af_destroy_window(self._wnd)) + +
[docs] def set_pos(self, x, y): + """ + Set the position of window on the screen. + + Parameters + ---------- + + x : int. + Pixel offset from left. + + y : int. + Pixel offset from top + + """ + safe_call(backend.get().af_set_position(self._wnd, c_int_t(x), c_int_t(y)))
+ +
[docs] def set_title(self, title): + """ + Set the title of the window + + Parameters + ---------- + + title : str. + Title used for the current window. + + """ + safe_call(backend.get().af_set_title(self._wnd, title))
+ +
[docs] def set_colormap(self, cmap): + """ + Set the colormap for the window. + + Parameters + ---------- + + cmap : af.COLORMAP. + Set the colormap for the window. + + """ + self._cmap = cmap
+ +
[docs] def set_size(self, w, h): + """ + Set the windo height and width. + + Parameters + ----------- + w : int + Width if window. + + h : int + Height of window. + """ + safe_call(backend.get().af_set_size(self._wnd, w, h))
+ +
[docs] def image(self, img, title=None): + """ + Display an arrayfire array as an image. + + Parameters + ---------- + + img: af.Array. + A 2 dimensional array for single channel image. + A 3 dimensional array for 3 channel image. + + title: str. + Title used for the image. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_image(self._wnd, img.arr, c_pointer(_cell)))
+ +
[docs] def scatter(self, X, Y, Z=None, points=None, marker=MARKER.POINT, title=None): + """ + Renders input arrays as 2D or 3D scatter plot. + + Parameters + ---------- + + X: af.Array. + A 1 dimensional array containing X co-ordinates. + + Y: af.Array. + A 1 dimensional array containing Y co-ordinates. + + Z: optional: af.Array. default: None. + - A 1 dimensional array containing Z co-ordinates. + - Not used if line is not None + + points: optional: af.Array. default: None. + - A 2 dimensional array of size [n 2]. Each column denotes X and Y co-ordinates for 2D scatter plot. + - A 3 dimensional array of size [n 3]. Each column denotes X, Y, and Z co-ordinates for 3D scatter plot. + + marker: af.MARKER + Specifies how the points look + + title: str. + Title used for the plot. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + + if points is None: + if Z is None: + safe_call(backend.get().af_draw_scatter_2d(self._wnd, X.arr, Y.arr, + marker.value, c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_scatter_3d(self._wnd, X.arr, Y.arr, Z.arr, + marker.value, c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_scatter_nd(self._wnd, points.arr, marker.value, c_pointer(_cell)))
+ +
[docs] def scatter2(self, points, marker=MARKER.POINT, title=None): + """ + Renders the input array as a 2D Scatter plot. + + Parameters + ---------- + + points: af.Array. + A 2 dimensional array containing (X,Y) co-ordinates. + + marker: af.MARKER + Specifies how the points look + + title: str. + Title used for the plot. + """ + assert(points.numdims() == 2) + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_scatter2(self._wnd, points.arr, + marker.value, c_pointer(_cell)))
+ +
[docs] def scatter3(self, points, marker=MARKER.POINT, title=None): + """ + Renders the input array as a 3D Scatter plot. + + Parameters + ---------- + + points: af.Array. + A 2 dimensional array containing (X,Y,Z) co-ordinates. + + marker: af.MARKER + Specifies how the points look + + title: str. + Title used for the plot. + """ + assert(points.numdims() == 3) + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_scatter3(self._wnd, points.arr, + marker.value, c_pointer(_cell)))
+
[docs] def plot(self, X, Y, Z=None, line = None, title=None): + """ + Display a 2D or 3D Plot. + + Parameters + ---------- + + X: af.Array. + - A 1 dimensional array containing X co-ordinates. + - Not used if line is not None + + Y: af.Array. + - A 1 dimensional array containing Y co-ordinates. + - Not used if line is not None + + Z: optional: af.Array. default: None. + - A 1 dimensional array containing Z co-ordinates. + - Not used if line is not None + + line: optional: af.Array. default: None. + - A 2 dimensional array of size [n 2]. Each column denotes X and Y co-ordinates for plotting 2D lines. + - A 3 dimensional array of size [n 3]. Each column denotes X, Y, and Z co-ordinates for plotting 3D lines. + + title: str. + Title used for the plot. + + Note + ---- + + The line parameter takes precedence. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + if line is None: + if Z is None: + safe_call(backend.get().af_draw_plot_2d(self._wnd, X.arr, Y.arr, c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_plot_3d(self._wnd, X.arr, Y.arr, Z.arr, c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_plot_nd(self._wnd, line.arr, c_pointer(_cell)))
+ +
[docs] def plot2(self, line, title=None): + """ + Display a 2D Plot. + + Parameters + ---------- + + line: af.Array. + - A 2 dimensional array of size [n 2]. Each column denotes X, and Y co-ordinates for plotting 2D lines. + + title: str. + Title used for the plot. + + """ + + assert(line.numdims() == 2) + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_plot_nd(self._wnd, line.arr, c_pointer(_cell)))
+ +
[docs] def plot3(self, X=None, Y=None, Z=None, line=None, title=None): + """ + Display a 3D Plot. + + Parameters + ---------- + + line: af.Array. + - A 3 dimensional array of size [n 3]. Each column denotes X, Y, and Z co-ordinates for plotting 3D lines. + + title: str. + Title used for the plot. + """ + + assert(line.numdims() == 3) + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_plot_nd(self._wnd, line.arr, c_pointer(_cell)))
+ +
[docs] def vector_field(self, xpoints, xdirs, ypoints, ydirs, zpoints=None, zdirs=None, + points = None, dirs = None, title=None): + """ + Display a 2D or 3D Vector_Field. + + Parameters + ---------- + + xpoints : af.Array. + - A 1 dimensional array containing X co-ordinates. + - Not used if points is not None + + xdirs : af.Array. + - A 1 dimensional array specifying direction at current location. + - Not used if dirs is not None + + ypoints : af.Array. + - A 1 dimensional array containing Y co-ordinates. + - Not used if points is not None + + ydirs : af.Array. + - A 1 dimensional array specifying direction at current location. + - Not used if dirs is not None + + zpoints : optional: af.Array. default: None. + - A 1 dimensional array containing Z co-ordinates. + - Not used if points is not None + + zdirs : optional: af.Array. default: none. + - A 1 dimensional array specifying direction at current location. + - Not used if dirs is not None + + points : optional: af.Array. default: None. + - A 2 dimensional array of size [n 2]. Each column denotes X and Y co-ordinates for plotting 2D lines. + - A 3 dimensional array of size [n 3]. Each column denotes X, Y, and Z co-ordinates for plotting 3D lines. + + dirs : optional: af.Array. default: None. + - A 2 dimensional array of size [n 2]. Each column denotes X and Y directions for plotting 2D lines. + - A 3 dimensional array of size [n 3]. Each column denotes X, Y, and Z directions for plotting 3D lines. + + title : str. + Title used for the plot. + + Note + ---- + + The line parameter takes precedence. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + if line is None: + if Z is None: + safe_call(backend.get().af_draw_vector_field_2d(self._wnd, + xpoints.arr, ypoints.arr, + xdirs.arr, ydirs.arr, + c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_vector_field_2d(self._wnd, + xpoints.arr, ypoints.arr, zpoints.arr, + xdirs.arr, ydirs.arr, zdirs.arr, + c_pointer(_cell))) + else: + safe_call(backend.get().af_draw_plot_nd(self._wnd, points.arr, dirs.arr, c_pointer(_cell)))
+ +
[docs] def surface(self, x_vals, y_vals, z_vals, title=None): + """ + Renders the input array as a 3D surface plot. + + Parameters + ---------- + + x_vals: af.Array. + A 1 dimensional array containing X co-ordinates. + + y_vals: af.Array. + A 1 dimensional array containing Y co-ordinates. + + z_vals: af.Array. + A 1 dimensional array containing Z co-ordinates. + + title: str. + Title used for the plot. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_surface(self._wnd, + x_vals.arr, y_vals.arr, z_vals.arr, + c_pointer(_cell)))
+ +
[docs] def hist(self, X, min_val, max_val, title=None): + """ + Display a histogram Plot. + + Parameters + ---------- + + X: af.Array. + A 1 dimensional array containing the histogram. + + min_val: scalar. + A scalar value specifying the lower bound of the histogram. + + max_val: scalar. + A scalar value specifying the upper bound of the histogram. + + title: str. + Title used for the histogram. + """ + _cell = _Cell(self._r, self._c, title, self._cmap) + safe_call(backend.get().af_draw_hist(self._wnd, X.arr, + c_double_t(max_val), c_double_t(min_val), + c_pointer(_cell)))
+ +
[docs] def grid(self, rows, cols): + """ + Create a grid for sub plotting within the window. + + Parameters + ---------- + + rows: int. + Number of rows in the grid. + + cols: int. + Number of columns in the grid. + + """ + safe_call(backend.get().af_grid(self._wnd, c_int_t(rows), c_int_t(cols)))
+ +
[docs] def show(self): + """ + Force the window to display the contents. + + Note: This is only needed when using the window as a grid. + """ + safe_call(backend.get().af_show(self._wnd))
+ +
[docs] def close(self): + """ + Close the window. + """ + tmp = c_bool_t(True) + safe_call(backend.get().af_is_window_closed(c_pointer(tmp), self._wnd)) + return tmp
+ +
[docs] def set_visibility(is_visible): + """ + A flag that shows or hides the window as requested. + + Parameters + ---------- + is_visible: Flag specifying the visibility of the flag. + """ + safe_call(backend.get().af_set_visibility(self._wnd, is_visible))
+ +
[docs] def set_axes_limits(self, xmin, xmax, ymin, ymax, zmin=None, zmax=None, exact=False): + """ + Set axis limits. + + Parameters + ---------- + + xmin : af.Array. + - lower limit of the x axis. + + xmax : af.Array. + - upper limit of the x axis. + + ymin : af.Array. + - lower limit of the y axis. + + ymax : af.Array. + - upper limit of the y axis. + + zmin : optional: af.Array. default: None. + - lower limit of the z axis. + + zmax : optional: af.Array. default: None. + - upper limit of the z axis. + + title : str. + Title used for the plot. + + Note + ---- + + The line parameter takes precedence. + """ + _cell = _Cell(self._r, self._c, "", self._cmap) + if (zmin is None or zmax is None): + safe_call(backend.get().af_set_axes_limits_2d(self._wnd, + c_float_t(xmin), c_float_t(xmax), + c_float_t(ymin), c_float_t(ymax), + exact, c_pointer(_cell))) + else: + safe_call(backend.get().af_set_axes_limits_2d(self._wnd, + c_float_t(xmin), c_float_t(xmax), + c_float_t(ymin), c_float_t(ymax), + c_float_t(zmin), c_float_t(zmax), + exact, c_pointer(_cell)))
+ +
[docs] def set_axes_label_format(self, xformat="4.1%f", yformat="4.1%f", zformat="4.1%f"): + """ + Set axis limits. + + Parameters + ---------- + + xformat : str. + default: "4.1%f". + is a printf-style format specifier for x-axis + yformat : str. + default: "4.1%f". + is a printf-style format specifier for y-axis + zformat : str. + default: "4.1%f". + is a printf-style format specifier for z-axis + + """ + _cell = _Cell(self._r, self._c, None, self._cmap) + xformat = xformat.encode("ascii") + yformat = yformat.encode("ascii") + zformat = zformat.encode("ascii") + safe_call(backend.get().af_set_axes_label_format(self._wnd, + c_char_ptr_t(xformat), + c_char_ptr_t(yformat), + c_char_ptr_t(zformat), + c_pointer(_cell)))
+ + def __getitem__(self, keys): + """ + Get access to a specific grid location within the window. + + Examples + -------- + + >>> a = af.randu(5,5) + >>> b = af.randu(5,5) + >>> w = af.Window() + >>> w.grid(1,2) + >>> w[0, 0].image(a) + >>> w[0, 1].image(b) + >>> w.show() + """ + if not isinstance(keys, tuple): + raise IndexError("Window expects indexing along two dimensions") + if len(keys) != 2: + raise IndexError("Window expects indexing along two dimensions only") + if not (_is_number(keys[0]) and _is_number(keys[1])): + raise IndexError("Window expects the indices to be numbers") + self._r = keys[0] + self._c = keys[1] + + return self
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/image.html b/_modules/arrayfire/image.html new file mode 100644 index 000000000..3b76c6e7d --- /dev/null +++ b/_modules/arrayfire/image.html @@ -0,0 +1,1507 @@ + + + + + + + + arrayfire.image — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.image

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Image processing functions.
+"""
+
+from .library import *
+from .array import *
+from .data import constant
+from .signal import medfilt
+import os
+
+
[docs]def gradient(image): + """ + Find the horizontal and vertical gradients. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + Returns + --------- + (dx, dy) : Tuple of af.Array. + - `dx` containing the horizontal gradients of `image`. + - `dy` containing the vertical gradients of `image`. + + """ + dx = Array() + dy = Array() + safe_call(backend.get().af_gradient(c_pointer(dx.arr), c_pointer(dy.arr), image.arr)) + return dx, dy
+ +
[docs]def load_image(file_name, is_color=False): + """ + Load an image on the disk as an array. + + Parameters + ---------- + file_name: str + - Full path of the file name on disk. + + is_color : optional: bool. default: False. + - Specifies if the image is loaded as 1 channel (if False) or 3 channel image (if True). + + Returns + ------- + image - af.Array + A 2 dimensional (1 channel) or 3 dimensional (3 channel) array containing the image. + + """ + assert(os.path.isfile(file_name)) + image = Array() + safe_call(backend.get().af_load_image(c_pointer(image.arr), + c_char_ptr_t(file_name.encode('ascii')), is_color)) + return image
+ +
[docs]def save_image(image, file_name): + """ + Save an array as an image on the disk. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image. + + file_name: str + - Full path of the file name on the disk. + """ + assert(isinstance(file_name, str)) + safe_call(backend.get().af_save_image(c_char_ptr_t(file_name.encode('ascii')), image.arr)) + return image
+ + +
[docs]def load_image_native(file_name): + """ + Load an image on the disk as an array in native format. + + Parameters + ---------- + file_name: str + - Full path of the file name on disk. + + Returns + ------- + image - af.Array + A 2 dimensional (1 channel) or 3 dimensional (3 or 4 channel) array containing the image. + + """ + assert(os.path.isfile(file_name)) + image = Array() + safe_call(backend.get().af_load_image_native(c_pointer(image.arr), + c_char_ptr_t(file_name.encode('ascii')))) + return image
+ +
[docs]def save_image_native(image, file_name): + """ + Save an array as an image on the disk in native format. + + Parameters + ---------- + image : af.Array + - A 2 or 3 dimensional arrayfire array representing an image. + + file_name: str + - Full path of the file name on the disk. + """ + assert(isinstance(file_name, str)) + safe_call(backend.get().af_save_image_native(c_char_ptr_t(file_name.encode('ascii')), image.arr)) + return image
+ +
[docs]def resize(image, scale=None, odim0=None, odim1=None, method=INTERP.NEAREST): + """ + Resize an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + scale : optional: scalar. default: None. + - Scale factor for the image resizing. + + odim0 : optional: int. default: None. + - Size of the first dimension of the output. + + odim1 : optional: int. default: None. + - Size of the second dimension of the output. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for resizing. + + Returns + --------- + out : af.Array + - Output image after resizing. + + Note + ----- + + - If `scale` is None, `odim0` and `odim1` need to be specified. + - If `scale` is not None, `odim0` and `odim1` are ignored. + + """ + if (scale is None): + assert(odim0 is not None) + assert(odim1 is not None) + else: + idims = image.dims() + odim0 = int(scale * idims[0]) + odim1 = int(scale * idims[1]) + + output = Array() + safe_call(backend.get().af_resize(c_pointer(output.arr), + image.arr, c_dim_t(odim0), + c_dim_t(odim1), method.value)) + + return output
+ +
[docs]def transform(image, trans_mat, odim0 = 0, odim1 = 0, method=INTERP.NEAREST, is_inverse=True): + """ + Transform an image using a transformation matrix. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + trans_mat : af.Array + - A 2 D floating point arrayfire array of size [3, 2]. + + odim0 : optional: int. default: 0. + - Size of the first dimension of the output. + + odim1 : optional: int. default: 0. + - Size of the second dimension of the output. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for transformation. + + is_inverse : optional: bool. default: True. + - Specifies if the inverse transform is applied. + + Returns + --------- + out : af.Array + - Output image after transformation. + + Note + ----- + + - If `odim0` and `odim` are 0, the output dimensions are automatically calculated by the function. + + """ + output = Array() + safe_call(backend.get().af_transform(c_pointer(output.arr), + image.arr, trans_mat.arr, + c_dim_t(odim0), c_dim_t(odim1), + method.value, is_inverse)) + return output
+ + +
[docs]def rotate(image, theta, is_crop = True, method = INTERP.NEAREST): + """ + Rotate an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + theta : scalar + - The angle to rotate in radians. + + is_crop : optional: bool. default: True. + - Specifies if the output should be cropped to the input size. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for rotating. + + Returns + --------- + out : af.Array + - Output image after rotating. + """ + output = Array() + safe_call(backend.get().af_rotate(c_pointer(output.arr), image.arr, + c_float_t(theta), is_crop, method.value)) + return output
+ +
[docs]def translate(image, trans0, trans1, odim0 = 0, odim1 = 0, method = INTERP.NEAREST): + """ + Translate an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + trans0: int. + - Translation along first dimension in pixels. + + trans1: int. + - Translation along second dimension in pixels. + + odim0 : optional: int. default: 0. + - Size of the first dimension of the output. + + odim1 : optional: int. default: 0. + - Size of the second dimension of the output. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for translation. + + Returns + --------- + out : af.Array + - Output image after translation. + + Note + ----- + + - If `odim0` and `odim` are 0, the output dimensions are automatically calculated by the function. + + """ + output = Array() + safe_call(backend.get().af_translate(c_pointer(output.arr), + image.arr, trans0, trans1, + c_dim_t(odim0), c_dim_t(odim1), method.value)) + return output
+ +
[docs]def scale(image, scale0, scale1, odim0 = 0, odim1 = 0, method = INTERP.NEAREST): + """ + Scale an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + scale0 : scalar. + - Scale factor for the first dimension. + + scale1 : scalar. + - Scale factor for the second dimension. + + odim0 : optional: int. default: None. + - Size of the first dimension of the output. + + odim1 : optional: int. default: None. + - Size of the second dimension of the output. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for resizing. + + Returns + --------- + out : af.Array + - Output image after scaling. + + Note + ----- + + - If `odim0` and `odim` are 0, the output dimensions are automatically calculated by the function. + + """ + output = Array() + safe_call(backend.get().af_scale(c_pointer(output.arr), + image.arr, c_float_t(scale0), c_float_t(scale1), + c_dim_t(odim0), c_dim_t(odim1), method.value)) + return output
+ +
[docs]def skew(image, skew0, skew1, odim0 = 0, odim1 = 0, method = INTERP.NEAREST, is_inverse=True): + """ + Skew an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + skew0 : scalar. + - Skew factor for the first dimension. + + skew1 : scalar. + - Skew factor for the second dimension. + + odim0 : optional: int. default: None. + - Size of the first dimension of the output. + + odim1 : optional: int. default: None. + - Size of the second dimension of the output. + + method : optional: af.INTERP. default: af.INTERP.NEAREST. + - Interpolation method used for resizing. + + is_inverse : optional: bool. default: True. + - Specifies if the inverse skew is applied. + + Returns + --------- + out : af.Array + - Output image after skewing. + + Note + ----- + + - If `odim0` and `odim` are 0, the output dimensions are automatically calculated by the function. + + """ + output = Array() + safe_call(backend.get().af_skew(c_pointer(output.arr), + image.arr, c_float_t(skew0), c_float_t(skew1), + c_dim_t(odim0), c_dim_t(odim1), + method.value, is_inverse)) + + return output
+ +
[docs]def histogram(image, nbins, min_val = None, max_val = None): + """ + Find the histogram of an image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + nbins : int. + - Number of bins in the histogram. + + min_val : optional: scalar. default: None. + - The lower bound for the bin values. + - If None, `af.min(image)` is used. + + max_val : optional: scalar. default: None. + - The upper bound for the bin values. + - If None, `af.max(image)` is used. + + Returns + --------- + hist : af.Array + - Containing the histogram of the image. + + """ + from .algorithm import min as af_min + from .algorithm import max as af_max + + if min_val is None: + min_val = af_min(image) + + if max_val is None: + max_val = af_max(image) + + output = Array() + safe_call(backend.get().af_histogram(c_pointer(output.arr), + image.arr, c_uint_t(nbins), + c_double_t(min_val), c_double_t(max_val))) + return output
+ +
[docs]def hist_equal(image, hist): + """ + Equalize an image based on a histogram. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + hist : af.Array + - Containing the histogram of an image. + + Returns + --------- + + output : af.Array + - The equalized image. + + """ + output = Array() + safe_call(backend.get().af_hist_equal(c_pointer(output.arr), image.arr, hist.arr)) + return output
+ +
[docs]def dilate(image, mask = None): + """ + Run image dilate on the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + mask : optional: af.Array. default: None. + - Specifies the neighborhood of a pixel. + - When None, a [3, 3] array of all ones is used. + + Returns + --------- + + output : af.Array + - The dilated image. + + """ + if mask is None: + mask = constant(1, 3, 3, dtype=Dtype.f32) + + output = Array() + safe_call(backend.get().af_dilate(c_pointer(output.arr), image.arr, mask.arr)) + + return output
+ +
[docs]def dilate3(volume, mask = None): + """ + Run volume dilate on a volume. + + Parameters + ---------- + volume : af.Array + - A 3 D arrayfire array representing a volume, or + - A multi dimensional array representing batch of volumes. + + mask : optional: af.Array. default: None. + - Specifies the neighborhood of a pixel. + - When None, a [3, 3, 3] array of all ones is used. + + Returns + --------- + + output : af.Array + - The dilated volume. + + """ + if mask is None: + mask = constant(1, 3, 3, 3, dtype=Dtype.f32) + + output = Array() + safe_call(backend.get().af_dilate3(c_pointer(output.arr), volume.arr, mask.arr)) + + return output
+ +
[docs]def erode(image, mask = None): + """ + Run image erode on the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + mask : optional: af.Array. default: None. + - Specifies the neighborhood of a pixel. + - When None, a [3, 3] array of all ones is used. + + Returns + --------- + + output : af.Array + - The eroded image. + + """ + if mask is None: + mask = constant(1, 3, 3, dtype=Dtype.f32) + + output = Array() + safe_call(backend.get().af_erode(c_pointer(output.arr), image.arr, mask.arr)) + + return output
+ +
[docs]def erode3(volume, mask = None): + """ + Run volume erode on the volume. + + Parameters + ---------- + volume : af.Array + - A 3 D arrayfire array representing an volume, or + - A multi dimensional array representing batch of volumes. + + mask : optional: af.Array. default: None. + - Specifies the neighborhood of a pixel. + - When None, a [3, 3, 3] array of all ones is used. + + Returns + --------- + + output : af.Array + - The eroded volume. + + """ + + if mask is None: + mask = constant(1, 3, 3, 3, dtype=Dtype.f32) + + output = Array() + safe_call(backend.get().af_erode3(c_pointer(output.arr), volume.arr, mask.arr)) + + return output
+ +
[docs]def bilateral(image, s_sigma, c_sigma, is_color = False): + """ + Apply bilateral filter to the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + s_sigma : scalar. + - Sigma value for the co-ordinate space. + + c_sigma : scalar. + - Sigma value for the color space. + + is_color : optional: bool. default: False. + - Specifies if the third dimension is 3rd channel (if True) or a batch (if False). + + Returns + --------- + + output : af.Array + - The image after the application of the bilateral filter. + + """ + output = Array() + safe_call(backend.get().af_bilateral(c_pointer(output.arr), + image.arr, c_float_t(s_sigma), + c_float_t(c_sigma), is_color)) + return output
+ +
[docs]def mean_shift(image, s_sigma, c_sigma, n_iter, is_color = False): + """ + Apply mean shift to the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + s_sigma : scalar. + - Sigma value for the co-ordinate space. + + c_sigma : scalar. + - Sigma value for the color space. + + n_iter : int. + - Number of mean shift iterations. + + is_color : optional: bool. default: False. + - Specifies if the third dimension is 3rd channel (if True) or a batch (if False). + + Returns + --------- + + output : af.Array + - The image after the application of the meanshift. + + """ + output = Array() + safe_call(backend.get().af_mean_shift(c_pointer(output.arr), + image.arr, c_float_t(s_sigma), c_float_t(c_sigma), + c_uint_t(n_iter), is_color)) + return output
+ +
[docs]def minfilt(image, w_len = 3, w_wid = 3, edge_pad = PAD.ZERO): + """ + Apply min filter for the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + w0 : optional: int. default: 3. + - The length of the filter along the first dimension. + + w1 : optional: int. default: 3. + - The length of the filter along the second dimension. + + edge_pad : optional: af.PAD. default: af.PAD.ZERO + - Flag specifying how the min at the edge should be treated. + + Returns + --------- + + output : af.Array + - The image after min filter is applied. + + """ + output = Array() + safe_call(backend.get().af_minfilt(c_pointer(output.arr), + image.arr, c_dim_t(w_len), + c_dim_t(w_wid), edge_pad.value)) + return output
+ +
[docs]def maxfilt(image, w_len = 3, w_wid = 3, edge_pad = PAD.ZERO): + """ + Apply max filter for the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + w0 : optional: int. default: 3. + - The length of the filter along the first dimension. + + w1 : optional: int. default: 3. + - The length of the filter along the second dimension. + + edge_pad : optional: af.PAD. default: af.PAD.ZERO + - Flag specifying how the max at the edge should be treated. + + Returns + --------- + + output : af.Array + - The image after max filter is applied. + + """ + output = Array() + safe_call(backend.get().af_maxfilt(c_pointer(output.arr), + image.arr, c_dim_t(w_len), + c_dim_t(w_wid), edge_pad.value)) + return output
+ +
[docs]def regions(image, conn = CONNECTIVITY.FOUR, out_type = Dtype.f32): + """ + Find the connected components in the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image. + + conn : optional: af.CONNECTIVITY. default: af.CONNECTIVITY.FOUR. + - Specifies the connectivity of the pixels. + + out_type : optional: af.Dtype. default: af.Dtype.f32. + - Specifies the type for the output. + + Returns + --------- + + output : af.Array + - An array where each pixel is labeled with its component number. + + """ + output = Array() + safe_call(backend.get().af_regions(c_pointer(output.arr), image.arr, + conn.value, out_type.value)) + return output
+ +
[docs]def confidenceCC(image, seedx, seedy, radius, multiplier, iters, segmented_value): + """ + Find the confidence connected components in the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image. + Expects non-integral type + + seedx : af.Array + - An array with x-coordinates of seed points + + seedy : af.Array + - An array with y-coordinates of seed points + + radius : scalar + - The neighborhood region to be considered around + each seed point + + multiplier : scalar + - Controls the threshold range computed from + the mean and variance of seed point neighborhoods + + iters : scalar + - is number of iterations + + segmented_value : scalar + - the value to which output array valid + pixels are set to. + + Returns + --------- + + output : af.Array + - Output array with resulting connected components + + """ + output = Array() + safe_call(backend.get().af_confidence_cc(c_pointer(output.arr), image.arr, seedx.arr, seedy.arr, + c_uint_t(radius), c_uint_t(multiplier), c_int_t(iters), c_double_t(segmented_value))) + return output
+ +
[docs]def sobel_derivatives(image, w_len=3): + """ + Find the sobel derivatives of the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + w_len : optional: int. default: 3. + - The size of the sobel operator. + + Returns + --------- + + (dx, dy) : tuple of af.Arrays. + - `dx` is the sobel derivative along the horizontal direction. + - `dy` is the sobel derivative along the vertical direction. + + """ + dx = Array() + dy = Array() + safe_call(backend.get().af_sobel_operator(c_pointer(dx.arr), c_pointer(dy.arr), + image.arr, c_uint_t(w_len))) + return dx,dy
+ +
[docs]def gaussian_kernel(rows, cols, sigma_r = None, sigma_c = None): + """ + Create a gaussian kernel with the given parameters. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + rows : int + - The number of rows in the gaussian kernel. + + cols : int + - The number of columns in the gaussian kernel. + + sigma_r : optional: number. default: None. + - The sigma value along rows + - If None, calculated as (0.25 * rows + 0.75) + + sigma_c : optional: number. default: None. + - The sigma value along columns + - If None, calculated as (0.25 * cols + 0.75) + + Returns + ------- + out : af.Array + - A gaussian kernel of size (rows, cols) + """ + out = Array() + + if (sigma_r is None): + sigma_r = 0.25 * rows + 0.75 + + if (sigma_c is None): + sigma_c = 0.25 * cols + 0.75 + + safe_call(backend.get().af_gaussian_kernel(c_pointer(out.arr), + c_int_t(rows), c_int_t(cols), + c_double_t(sigma_r), c_double_t(sigma_c))) + return out
+ +
[docs]def sobel_filter(image, w_len = 3, is_fast = False): + """ + Apply sobel filter to the image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + w_len : optional: int. default: 3. + - The size of the sobel operator. + + is_fast : optional: bool. default: False. + - Specifies if the magnitude is generated using SAD (if True) or SSD (if False). + + Returns + --------- + + output : af.Array + - Image containing the magnitude of the sobel derivatives. + + """ + from .arith import abs as af_abs + from .arith import hypot as af_hypot + + dx,dy = sobel_derivatives(image, w_len) + if (is_fast): + return af_abs(dx) + af_abs(dy) + else: + return af_hypot(dx, dy)
+ +
[docs]def rgb2gray(image, r_factor = 0.2126, g_factor = 0.7152, b_factor = 0.0722): + """ + Convert RGB image to Grayscale. + + Parameters + ---------- + image : af.Array + - A 3 D arrayfire array representing an 3 channel image, or + - A multi dimensional array representing batch of images. + + r_factor : optional: scalar. default: 0.2126. + - Weight for the red channel. + + g_factor : optional: scalar. default: 0.7152. + - Weight for the green channel. + + b_factor : optional: scalar. default: 0.0722. + - Weight for the blue channel. + + Returns + -------- + + output : af.Array + - A grayscale image. + + """ + output=Array() + safe_call(backend.get().af_rgb2gray(c_pointer(output.arr), + image.arr, c_float_t(r_factor), c_float_t(g_factor), c_float_t(b_factor))) + return output
+ +
[docs]def gray2rgb(image, r_factor = 1.0, g_factor = 1.0, b_factor = 1.0): + """ + Convert Grayscale image to an RGB image. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + r_factor : optional: scalar. default: 1.0. + - Scale factor for the red channel. + + g_factor : optional: scalar. default: 1.0. + - Scale factor for the green channel. + + b_factor : optional: scalar. default: 1.0 + - Scale factor for the blue channel. + + Returns + -------- + + output : af.Array + - An RGB image. + - The channels are not coalesced, i.e. they appear along the third dimension. + + """ + output=Array() + safe_call(backend.get().af_gray2rgb(c_pointer(output.arr), + image.arr, c_float_t(r_factor), c_float_t(g_factor), c_float_t(b_factor))) + return output
+ +
[docs]def hsv2rgb(image): + """ + Convert HSV image to RGB. + + Parameters + ---------- + image : af.Array + - A 3 D arrayfire array representing an 3 channel image, or + - A multi dimensional array representing batch of images. + + Returns + -------- + + output : af.Array + - A HSV image. + + """ + output = Array() + safe_call(backend.get().af_hsv2rgb(c_pointer(output.arr), image.arr)) + return output
+ +
[docs]def rgb2hsv(image): + """ + Convert RGB image to HSV. + + Parameters + ---------- + image : af.Array + - A 3 D arrayfire array representing an 3 channel image, or + - A multi dimensional array representing batch of images. + + Returns + -------- + + output : af.Array + - A RGB image. + + """ + output = Array() + safe_call(backend.get().af_rgb2hsv(c_pointer(output.arr), image.arr)) + return output
+ +
[docs]def color_space(image, to_type, from_type): + """ + Convert an image from one color space to another. + + Parameters + ---------- + image : af.Array + - A multi dimensional array representing batch of images in `from_type` color space. + + to_type : af.CSPACE + - An enum for the destination color space. + + from_type : af.CSPACE + - An enum for the source color space. + + Returns + -------- + + output : af.Array + - An image in the `to_type` color space. + + """ + output = Array() + safe_call(backend.get().af_color_space(c_pointer(output.arr), image.arr, + to_type.value, from_type.value)) + return output
+ +
[docs]def unwrap(image, wx, wy, sx, sy, px=0, py=0, is_column=True): + """ + Unrwap an image into an array. + + Parameters + ---------- + + image : af.Array + A multi dimensional array specifying an image or batch of images. + + wx : Integer. + Block window size along the first dimension. + + wy : Integer. + Block window size along the second dimension. + + sx : Integer. + Stride along the first dimension. + + sy : Integer. + Stride along the second dimension. + + px : Integer. Optional. Default: 0 + Padding along the first dimension. + + py : Integer. Optional. Default: 0 + Padding along the second dimension. + + is_column : Boolean. Optional. Default: True. + Specifies if the patch should be laid along row or columns. + + Returns + ------- + + out : af.Array + A multi dimensional array contianing the image patches along specified dimension. + + Examples + -------- + >>> import arrayfire as af + >>> a = af.randu(6, 6) + >>> af.display(a) + + [6 6 1 1] + 0.4107 0.3775 0.0901 0.8060 0.0012 0.9250 + 0.8224 0.3027 0.5933 0.5938 0.8703 0.3063 + 0.9518 0.6456 0.1098 0.8395 0.5259 0.9313 + 0.1794 0.5591 0.1046 0.1933 0.1443 0.8684 + 0.4198 0.6600 0.8827 0.7270 0.3253 0.6592 + 0.0081 0.0764 0.1647 0.0322 0.5081 0.4387 + + >>> b = af.unwrap(a, 2, 2, 2, 2) + >>> af.display(b) + + [4 9 1 1] + 0.4107 0.9518 0.4198 0.0901 0.1098 0.8827 0.0012 0.5259 0.3253 + 0.8224 0.1794 0.0081 0.5933 0.1046 0.1647 0.8703 0.1443 0.5081 + 0.3775 0.6456 0.6600 0.8060 0.8395 0.7270 0.9250 0.9313 0.6592 + 0.3027 0.5591 0.0764 0.5938 0.1933 0.0322 0.3063 0.8684 0.4387 + """ + + out = Array() + safe_call(backend.get().af_unwrap(c_pointer(out.arr), image.arr, + c_dim_t(wx), c_dim_t(wy), + c_dim_t(sx), c_dim_t(sy), + c_dim_t(px), c_dim_t(py), + is_column)) + return out
+ +
[docs]def wrap(a, ox, oy, wx, wy, sx, sy, px=0, py=0, is_column=True): + """ + Wrap an array into an image. + + Parameters + ---------- + + a : af.Array + A multi dimensional array containing patches of images. + + wx : Integer. + Block window size along the first dimension. + + wy : Integer. + Block window size along the second dimension. + + sx : Integer. + Stride along the first dimension. + + sy : Integer. + Stride along the second dimension. + + px : Integer. Optional. Default: 0 + Padding along the first dimension. + + py : Integer. Optional. Default: 0 + Padding along the second dimension. + + is_column : Boolean. Optional. Default: True. + Specifies if the patch should be laid along row or columns. + + Returns + ------- + + out : af.Array + A multi dimensional array contianing the images. + + + Examples + -------- + >>> import arrayfire as af + >>> a = af.randu(6, 6) + >>> af.display(a) + + [6 6 1 1] + 0.4107 0.3775 0.0901 0.8060 0.0012 0.9250 + 0.8224 0.3027 0.5933 0.5938 0.8703 0.3063 + 0.9518 0.6456 0.1098 0.8395 0.5259 0.9313 + 0.1794 0.5591 0.1046 0.1933 0.1443 0.8684 + 0.4198 0.6600 0.8827 0.7270 0.3253 0.6592 + 0.0081 0.0764 0.1647 0.0322 0.5081 0.4387 + + >>> b = af.unwrap(a, 2, 2, 2, 2) + >>> af.display(b) + + [4 9 1 1] + 0.4107 0.9518 0.4198 0.0901 0.1098 0.8827 0.0012 0.5259 0.3253 + 0.8224 0.1794 0.0081 0.5933 0.1046 0.1647 0.8703 0.1443 0.5081 + 0.3775 0.6456 0.6600 0.8060 0.8395 0.7270 0.9250 0.9313 0.6592 + 0.3027 0.5591 0.0764 0.5938 0.1933 0.0322 0.3063 0.8684 0.4387 + + >>> af.display(c) + + [6 6 1 1] + 0.4107 0.3775 0.0901 0.8060 0.0012 0.9250 + 0.8224 0.3027 0.5933 0.5938 0.8703 0.3063 + 0.9518 0.6456 0.1098 0.8395 0.5259 0.9313 + 0.1794 0.5591 0.1046 0.1933 0.1443 0.8684 + 0.4198 0.6600 0.8827 0.7270 0.3253 0.6592 + 0.0081 0.0764 0.1647 0.0322 0.5081 0.4387 + + + """ + + out = Array() + safe_call(backend.get().af_wrap(c_pointer(out.arr), a.arr, + c_dim_t(ox), c_dim_t(oy), + c_dim_t(wx), c_dim_t(wy), + c_dim_t(sx), c_dim_t(sy), + c_dim_t(px), c_dim_t(py), + is_column)) + return out
+ +
[docs]def sat(image): + """ + Summed Area Tables + + Parameters + ---------- + image : af.Array + A multi dimensional array specifying image or batch of images + + Returns + ------- + out : af.Array + A multi dimensional array containing the summed area table of input image + """ + + out = Array() + safe_call(backend.get().af_sat(c_pointer(out.arr), image.arr)) + return out
+ +
[docs]def ycbcr2rgb(image, standard=YCC_STD.BT_601): + """ + YCbCr to RGB colorspace conversion. + + Parameters + ---------- + + image : af.Array + A multi dimensional array containing an image or batch of images in YCbCr format. + + standard: YCC_STD. optional. default: YCC_STD.BT_601 + - Specifies the YCbCr format. + - Can be one of YCC_STD.BT_601, YCC_STD.BT_709, and YCC_STD.BT_2020. + + Returns + -------- + + out : af.Array + A multi dimensional array containing an image or batch of images in RGB format + + """ + + out = Array() + safe_call(backend.get().af_ycbcr2rgb(c_pointer(out.arr), image.arr, standard.value)) + return out
+ +
[docs]def rgb2ycbcr(image, standard=YCC_STD.BT_601): + """ + RGB to YCbCr colorspace conversion. + + Parameters + ---------- + + image : af.Array + A multi dimensional array containing an image or batch of images in RGB format. + + standard: YCC_STD. optional. default: YCC_STD.BT_601 + - Specifies the YCbCr format. + - Can be one of YCC_STD.BT_601, YCC_STD.BT_709, and YCC_STD.BT_2020. + + Returns + -------- + + out : af.Array + A multi dimensional array containing an image or batch of images in YCbCr format + + """ + + out = Array() + safe_call(backend.get().af_rgb2ycbcr(c_pointer(out.arr), image.arr, standard.value)) + return out
+ +
[docs]def moments(image, moment = MOMENT.FIRST_ORDER): + """ + Calculate image moments. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image, or + - A multi dimensional array representing batch of images. + + moment : optional: af.MOMENT. default: af.MOMENT.FIRST_ORDER. + Moment(s) to calculate. Can be one of: + - af.MOMENT.M00 + - af.MOMENT.M01 + - af.MOMENT.M10 + - af.MOMENT.M11 + - af.MOMENT.FIRST_ORDER + + Returns + --------- + out : af.Array + - array containing requested moment(s) of each image + """ + output = Array() + safe_call(backend.get().af_moments(c_pointer(output.arr), image.arr, moment.value)) + return output
+ +
[docs]def canny(image, + low_threshold, high_threshold = None, + threshold_type = CANNY_THRESHOLD.MANUAL, + sobel_window = 3, is_fast = False): + """ + Canny edge detector. + + Parameters + ---------- + image : af.Array + - A 2 D arrayfire array representing an image + + threshold_type : optional: af.CANNY_THRESHOLD. default: af.CANNY_THRESHOLD.MANUAL. + Can be one of: + - af.CANNY_THRESHOLD.MANUAL + - af.CANNY_THRESHOLD.AUTO_OTSU + + low_threshold : required: float. + Specifies the % of maximum in gradient image if threshold_type is MANUAL. + Specifies the % of auto dervied high value if threshold_type is AUTO_OTSU. + + high_threshold : optional: float. default: None + Specifies the % of maximum in gradient image if threshold_type is MANUAL. + Ignored if threshold_type is AUTO_OTSU + + sobel_window : optional: int. default: 3 + Specifies the size of sobel kernel when computing the gradient image. + + Returns + -------- + + out : af.Array + - A binary image containing the edges + + """ + output = Array() + if threshold_type.value == CANNY_THRESHOLD.MANUAL.value: + assert(high_threshold is not None) + + high_threshold = high_threshold if high_threshold else 0 + safe_call(backend.get().af_canny(c_pointer(output.arr), image.arr, + c_int_t(threshold_type.value), + c_float_t(low_threshold), c_float_t(high_threshold), + c_uint_t(sobel_window), c_bool_t(is_fast))) + return output
+ +
[docs]def anisotropic_diffusion(image, time_step, conductance, iterations, flux_function_type = FLUX.QUADRATIC, diffusion_kind = DIFFUSION.GRAD): + """ + Anisotropic smoothing filter. + + Parameters + ---------- + image: af.Array + The input image. + + time_step: scalar. + The time step used in solving the diffusion equation. + + conductance: + Controls conductance sensitivity in diffusion equation. + + iterations: + Number of times the diffusion step is performed. + + flux_function_type: + Type of flux function to be used. Available flux functions: + - Quadratic (af.FLUX.QUADRATIC) + - Exponential (af.FLUX.EXPONENTIAL) + + diffusion_kind: + Type of diffusion equatoin to be used. Available diffusion equations: + - Gradient diffusion equation (af.DIFFUSION.GRAD) + - Modified curvature diffusion equation (af.DIFFUSION.MCDE) + + Returns + ------- + out: af.Array + Anisotropically-smoothed output image. + + """ + out = Array() + safe_call(backend.get(). + af_anisotropic_diffusion(c_pointer(out.arr), image.arr, + c_float_t(time_step), c_float_t(conductance), c_uint_t(iterations), + flux_function_type.value, diffusion_kind.value)) + return out
+ +
[docs]def iterativeDeconv(image, psf, iterations, relax_factor, algo = ITERATIVE_DECONV.DEFAULT): + """ + Iterative deconvolution algorithm. + + Parameters + ---------- + image: af.Array + The blurred input image. + + psf: af.Array + The kernel(point spread function) known to have caused + the blur in the system. + + iterations: + Number of times the algorithm will run. + + relax_factor: scalar. + is the relaxation factor multiplied with distance + of estimate from observed image. + + algo: + takes enum value of type af.ITERATIVE_DECONV + indicating the iterative deconvolution algorithm to be used + + Returns + ------- + out: af.Array + sharp image estimate generated from the blurred input + + Note + ------- + relax_factor argument is ignored when the RICHARDSONLUCY algorithm is used. + + """ + out = Array() + safe_call(backend.get(). + af_iterative_deconv(c_pointer(out.arr), image.arr, psf.arr, + c_uint_t(iterations), c_float_t(relax_factor), algo.value)) + return out
+ +
[docs]def inverseDeconv(image, psf, gamma, algo = ITERATIVE_DECONV.DEFAULT): + """ + Inverse deconvolution algorithm. + + Parameters + ---------- + image: af.Array + The blurred input image. + + psf: af.Array + The kernel(point spread function) known to have caused + the blur in the system. + + gamma: scalar. + is a user defined regularization constant + + algo: + takes enum value of type af.INVERSE_DECONV + indicating the inverse deconvolution algorithm to be used + + Returns + ------- + out: af.Array + sharp image estimate generated from the blurred input + + """ + out = Array() + safe_call(backend.get(). + af_inverse_deconv(c_pointer(out.arr), image.arr, psf.arr, + c_float_t(gamma), algo.value)) + return out
+ +
[docs]def is_image_io_available(): + """ + Function to check if the arrayfire library was built with Image IO support. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_image_io_available(c_pointer(res))) + return res.value
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/index.html b/_modules/arrayfire/index.html new file mode 100644 index 000000000..f4f010f92 --- /dev/null +++ b/_modules/arrayfire/index.html @@ -0,0 +1,353 @@ + + + + + + + + arrayfire.index — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.index

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+"""
+Index and Seq classes used in indexing operations.
+"""
+
+from .library import *
+from .util import *
+from .util import _is_number
+from .base import *
+from .bcast import _bcast_var
+import math
+
+
[docs]class Seq(ct.Structure): + """ + arrayfire equivalent of slice + + Attributes + ---------- + + begin: number + Start of the sequence. + + end : number + End of sequence. + + step : number + Step size. + + Parameters + ---------- + + S: slice or number. + + """ + _fields_ = [("begin", c_double_t), + ("end" , c_double_t), + ("step" , c_double_t)] + + def __init__ (self, S): + self.begin = c_double_t( 0) + self.end = c_double_t(-1) + self.step = c_double_t( 1) + + if _is_number(S): + self.begin = c_double_t(S) + self.end = c_double_t(S) + elif isinstance(S, slice): + if (S.step is not None): + self.step = c_double_t(S.step) + if(S.step < 0): + self.begin, self.end = self.end, self.begin + if (S.start is not None): + self.begin = c_double_t(S.start) + if (S.stop is not None): + self.end = c_double_t(S.stop) + + # handle special cases + if self.begin >= 0 and self.end >=0 and self.end <= self.begin and self.step >= 0: + self.begin = 1 + self.end = 1 + self.step = 1 + elif self.begin < 0 and self.end < 0 and self.end >= self.begin and self.step <= 0: + self.begin = -2 + self.end = -2 + self.step = -1 + + if (S.stop is not None): + self.end = self.end - math.copysign(1, self.step) + else: + raise IndexError("Invalid type while indexing arrayfire.array")
+ +
[docs]class ParallelRange(Seq): + + """ + Class used to parallelize for loop. + + Inherits from Seq. + + Attributes + ---------- + + S: slice + + Parameters + ---------- + + start: number + Beginning of parallel range. + + stop : number + End of parallel range. + + step : number + Step size for parallel range. + + Examples + -------- + + >>> import arrayfire as af + >>> a = af.randu(3, 3) + >>> b = af.randu(3, 1) + >>> c = af.constant(0, 3, 3) + >>> for ii in af.ParallelRange(3): + ... c[:, ii] = a[:, ii] + b + ... + >>> af.display(a) + [3 3 1 1] + 0.4107 0.1794 0.3775 + 0.8224 0.4198 0.3027 + 0.9518 0.0081 0.6456 + + >>> af.display(b) + [3 1 1 1] + 0.7269 + 0.7104 + 0.5201 + + >>> af.display(c) + [3 3 1 1] + 1.1377 0.9063 1.1045 + 1.5328 1.1302 1.0131 + 1.4719 0.5282 1.1657 + + """ + def __init__(self, start, stop=None, step=None): + + if (stop is None): + stop = start + start = 0 + + self.S = slice(start, stop, step) + super(ParallelRange, self).__init__(self.S) + + def __iter__(self): + return self + +
[docs] def next(self): + """ + Function called by the iterator in Python 2 + """ + if _bcast_var.get() is True: + _bcast_var.toggle() + raise StopIteration + else: + _bcast_var.toggle() + return self
+ + def __next__(self): + """ + Function called by the iterator in Python 3 + """ + return self.next()
+ +class _uidx(ct.Union): + _fields_ = [("arr", c_void_ptr_t), + ("seq", Seq)] + +
[docs]class Index(ct.Structure): + _fields_ = [("idx", _uidx), + ("isSeq", c_bool_t), + ("isBatch", c_bool_t)] + + """ + Container for the index class in arrayfire C library + + Attributes + ---------- + idx.arr: ctypes.c_void_p + - Default 0 + + idx.seq: af.Seq + - Default af.Seq(0, -1, 1) + + isSeq : bool + - Default True + + isBatch : bool + - Default False + + Parameters + ----------- + + idx: key + - If of type af.Array, self.idx.arr = idx, self.isSeq = False + - If of type af.ParallelRange, self.idx.seq = idx, self.isBatch = True + - Default:, self.idx.seq = af.Seq(idx) + + Note + ---- + + Implemented for internal use only. Use with extreme caution. + + """ + + def __init__ (self, idx): + + self.idx = _uidx() + self.isBatch = False + self.isSeq = True + + if isinstance(idx, BaseArray): + + arr = c_void_ptr_t(0) + + if (idx.type() == Dtype.b8.value): + safe_call(backend.get().af_where(c_pointer(arr), idx.arr)) + else: + safe_call(backend.get().af_retain_array(c_pointer(arr), idx.arr)) + + self.idx.arr = arr + self.isSeq = False + elif isinstance(idx, ParallelRange): + self.idx.seq = idx + self.isBatch = True + else: + self.idx.seq = Seq(idx) + + def __del__(self): + if not self.isSeq: + # ctypes field variables are automatically + # converted to basic C types so we have to + # build the void_p from the value again. + arr = c_void_ptr_t(self.idx.arr) + backend.get().af_release_array(arr)
+ +_span = Index(slice(None)) +class _Index4(object): + def __init__(self): + index_vec = Index * 4 + self.array = index_vec(_span, _span, _span, _span) + # Do not lose those idx as self.array keeps + # no reference to them. Otherwise the destructor + # is prematurely called + self.idxs = [_span, _span, _span, _span] + @property + def pointer(self): + return c_pointer(self.array) + + def __getitem__(self, idx): + return self.array[idx] + + def __setitem__(self, idx, value): + self.array[idx] = value + self.idxs[idx] = value +
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/interop.html b/_modules/arrayfire/interop.html new file mode 100644 index 000000000..a78939ab4 --- /dev/null +++ b/_modules/arrayfire/interop.html @@ -0,0 +1,395 @@ + + + + + + + + arrayfire.interop — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.interop

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Interop with other python packages.
+
+This module provides helper functions to copy data to arrayfire from the following modules:
+
+     1. numpy - numpy.ndarray
+     2. pycuda - pycuda.gpuarray
+     3. pyopencl - pyopencl.array
+     4. numba - numba.cuda.cudadrv.devicearray.DeviceNDArray
+
+"""
+
+from .array import *
+from .device import *
+
+
+def _fc_to_af_array(in_ptr, in_shape, in_dtype, is_device=False, copy = True):
+    """
+    Fortran Contiguous to af array
+    """
+    res = Array(in_ptr, in_shape, in_dtype, is_device=is_device)
+
+    if not is_device:
+        return res
+
+    lock_array(res)
+    return res.copy() if copy else res
+
+def _cc_to_af_array(in_ptr, ndim, in_shape, in_dtype, is_device=False, copy = True):
+    """
+    C Contiguous to af array
+    """
+    if ndim == 1:
+        return _fc_to_af_array(in_ptr, in_shape, in_dtype, is_device, copy)
+    else:
+        shape = tuple(reversed(in_shape))
+        res = Array(in_ptr, shape, in_dtype, is_device=is_device)
+        if is_device: lock_array(res)
+        return res._reorder()
+
+_nptype_to_aftype = {'b1' : Dtype.b8,
+		     'u1' : Dtype.u8,
+		     'u2' : Dtype.u16,
+		     'i2' : Dtype.s16,
+		     's4' : Dtype.u32,
+		     'i4' : Dtype.s32,
+		     'f4' : Dtype.f32,
+		     'c8' : Dtype.c32,
+		     's8' : Dtype.u64,
+		     'i8' : Dtype.s64,
+                     'f8' : Dtype.f64,
+                     'c16' : Dtype.c64}
+
+try:
+    import numpy as np
+except ImportError:
+    AF_NUMPY_FOUND=False
+else:
+    from numpy import ndarray as NumpyArray
+    from .data import reorder
+
+    AF_NUMPY_FOUND=True
+
+
[docs] def np_to_af_array(np_arr, copy=True): + """ + Convert numpy.ndarray to arrayfire.Array. + + Parameters + ---------- + np_arr : numpy.ndarray() + + copy : Bool specifying if array is to be copied. + Default is true. + Can only be False if array is fortran contiguous. + + Returns + --------- + af_arr : arrayfire.Array() + """ + + in_shape = np_arr.shape + in_ptr = np_arr.ctypes.data_as(c_void_ptr_t) + in_dtype = _nptype_to_aftype[np_arr.dtype.str[1:]] + + if not copy: + raise RuntimeError("Copy can not be False for numpy arrays") + + if (np_arr.flags['F_CONTIGUOUS']): + return _fc_to_af_array(in_ptr, in_shape, in_dtype) + elif (np_arr.flags['C_CONTIGUOUS']): + return _cc_to_af_array(in_ptr, np_arr.ndim, in_shape, in_dtype) + else: + return np_to_af_array(np_arr.copy())
+ + from_ndarray = np_to_af_array + +try: + import pycuda.gpuarray +except ImportError: + AF_PYCUDA_FOUND=False +else: + from pycuda.gpuarray import GPUArray as CudaArray + AF_PYCUDA_FOUND=True + + def pycuda_to_af_array(pycu_arr, copy=True): + """ + Convert pycuda.gpuarray to arrayfire.Array + + Parameters + ----------- + pycu_arr : pycuda.GPUArray() + + copy : Bool specifying if array is to be copied. + Default is true. + Can only be False if array is fortran contiguous. + + Returns + ---------- + af_arr : arrayfire.Array() + + Note + ---------- + The input array is copied to af.Array + """ + + in_ptr = pycu_arr.ptr + in_shape = pycu_arr.shape + in_dtype = pycu_arr.dtype.char + + if not copy and not pycu_arr.flags.f_contiguous: + raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") + + if (pycu_arr.flags.f_contiguous): + return _fc_to_af_array(in_ptr, in_shape, in_dtype, True, copy) + elif (pycu_arr.flags.c_contiguous): + return _cc_to_af_array(in_ptr, pycu_arr.ndim, in_shape, in_dtype, True, copy) + else: + return pycuda_to_af_array(pycu_arr.copy()) + +try: + from pyopencl.array import Array as OpenclArray +except ImportError: + AF_PYOPENCL_FOUND=False +else: + from .opencl import add_device_context as _add_device_context + from .opencl import set_device_context as _set_device_context + from .opencl import get_device_id as _get_device_id + from .opencl import get_context as _get_context + AF_PYOPENCL_FOUND=True + + def pyopencl_to_af_array(pycl_arr, copy=True): + """ + Convert pyopencl.gpuarray to arrayfire.Array + + Parameters + ----------- + pycl_arr : pyopencl.Array() + + copy : Bool specifying if array is to be copied. + Default is true. + Can only be False if array is fortran contiguous. + + Returns + ---------- + af_arr : arrayfire.Array() + + Note + ---------- + The input array is copied to af.Array + """ + + ctx = pycl_arr.context.int_ptr + que = pycl_arr.queue.int_ptr + dev = pycl_arr.queue.device.int_ptr + + dev_idx = None + ctx_idx = None + for n in range(get_device_count()): + set_device(n) + dev_idx = _get_device_id() + ctx_idx = _get_context() + if (dev_idx == dev and ctx_idx == ctx): + break + + if (dev_idx == None or ctx_idx == None or + dev_idx != dev or ctx_idx != ctx): + print("Adding context and queue") + _add_device_context(dev, ctx, que) + _set_device_context(dev, ctx) + + info() + in_ptr = pycl_arr.base_data.int_ptr + in_shape = pycl_arr.shape + in_dtype = pycl_arr.dtype.char + + if not copy and not pycl_arr.flags.f_contiguous: + raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") + + print("Copying array") + print(pycl_arr.base_data.int_ptr) + if (pycl_arr.flags.f_contiguous): + return _fc_to_af_array(in_ptr, in_shape, in_dtype, True, copy) + elif (pycl_arr.flags.c_contiguous): + return _cc_to_af_array(in_ptr, pycl_arr.ndim, in_shape, in_dtype, True, copy) + else: + return pyopencl_to_af_array(pycl_arr.copy()) + +try: + import numba +except ImportError: + AF_NUMBA_FOUND=False +else: + from numba import cuda + NumbaCudaArray = cuda.cudadrv.devicearray.DeviceNDArray + AF_NUMBA_FOUND=True + + def numba_to_af_array(nb_arr, copy=True): + """ + Convert numba.gpuarray to arrayfire.Array + + Parameters + ----------- + nb_arr : numba.cuda.cudadrv.devicearray.DeviceNDArray() + + copy : Bool specifying if array is to be copied. + Default is true. + Can only be False if array is fortran contiguous. + + Returns + ---------- + af_arr : arrayfire.Array() + + Note + ---------- + The input array is copied to af.Array + """ + + in_ptr = nb_arr.device_ctypes_pointer.value + in_shape = nb_arr.shape + in_dtype = _nptype_to_aftype[nb_arr.dtype.str[1:]] + + if not copy and not nb_arr.flags.f_contiguous: + raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") + + if (nb_arr.is_f_contiguous()): + return _fc_to_af_array(in_ptr, in_shape, in_dtype, True, copy) + elif (nb_arr.is_c_contiguous()): + return _cc_to_af_array(in_ptr, nb_arr.ndim, in_shape, in_dtype, True, copy) + else: + return numba_to_af_array(nb_arr.copy()) + +
[docs]def to_array(in_array, copy = True): + """ + Helper function to convert input from a different module to af.Array + + Parameters + ------------- + + in_array : array like object + Can be one of the following: + - numpy.ndarray + - pycuda.GPUArray + - pyopencl.Array + - numba.cuda.cudadrv.devicearray.DeviceNDArray + - array.array + - list + copy : Bool specifying if array is to be copied. + Default is true. + Can only be False if array is fortran contiguous. + + Returns + -------------- + af.Array of same dimensions as input after copying the data from the input + + """ + if AF_NUMPY_FOUND and isinstance(in_array, NumpyArray): + return np_to_af_array(in_array, copy) + if AF_PYCUDA_FOUND and isinstance(in_array, CudaArray): + return pycuda_to_af_array(in_array, copy) + if AF_PYOPENCL_FOUND and isinstance(in_array, OpenclArray): + return pyopencl_to_af_array(in_array, copy) + if AF_NUMBA_FOUND and isinstance(in_array, NumbaCudaArray): + return numba_to_af_array(in_array, copy) + return Array(src=in_array)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/lapack.html b/_modules/arrayfire/lapack.html new file mode 100644 index 000000000..feb178133 --- /dev/null +++ b/_modules/arrayfire/lapack.html @@ -0,0 +1,554 @@ + + + + + + + + arrayfire.lapack — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.lapack

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Dense Linear Algebra functions (solve, inverse, etc).
+"""
+
+from .library import *
+from .array import *
+
+
[docs]def lu(A): + """ + LU decomposition. + + Parameters + ---------- + A: af.Array + A 2 dimensional arrayfire array. + + Returns + ------- + (L,U,P): tuple of af.Arrays + - L - Lower triangular matrix. + - U - Upper triangular matrix. + - P - Permutation array. + + Note + ---- + + The original matrix `A` can be reconstructed using the outputs in the following manner. + + >>> A[P, :] = af.matmul(L, U) + + """ + L = Array() + U = Array() + P = Array() + safe_call(backend.get().af_lu(c_pointer(L.arr), c_pointer(U.arr), c_pointer(P.arr), A.arr)) + return L,U,P
+ +
[docs]def lu_inplace(A, pivot="lapack"): + """ + In place LU decomposition. + + Parameters + ---------- + A: af.Array + - a 2 dimensional arrayfire array on entry. + - Contains L in the lower triangle on exit. + - Contains U in the upper triangle on exit. + + Returns + ------- + P: af.Array + - Permutation array. + + Note + ---- + + This function is primarily used with `af.solve_lu` to reduce computations. + + """ + P = Array() + is_pivot_lapack = False if (pivot == "full") else True + safe_call(backend.get().af_lu_inplace(c_pointer(P.arr), A.arr, is_pivot_lapack)) + return P
+ +
[docs]def qr(A): + """ + QR decomposition. + + Parameters + ---------- + A: af.Array + A 2 dimensional arrayfire array. + + Returns + ------- + (Q,R,T): tuple of af.Arrays + - Q - Orthogonal matrix. + - R - Upper triangular matrix. + - T - Vector containing additional information to solve a least squares problem. + + Note + ---- + + The outputs of this funciton have the following properties. + + >>> A = af.matmul(Q, R) + >>> I = af.matmulNT(Q, Q) # Identity matrix + """ + Q = Array() + R = Array() + T = Array() + safe_call(backend.get().af_qr(c_pointer(Q.arr), c_pointer(R.arr), c_pointer(T.arr), A.arr)) + return Q,R,T
+ +
[docs]def qr_inplace(A): + """ + In place QR decomposition. + + Parameters + ---------- + A: af.Array + - a 2 dimensional arrayfire array on entry. + - Packed Q and R matrices on exit. + + Returns + ------- + T: af.Array + - Vector containing additional information to solve a least squares problem. + + Note + ---- + + This function is used to save space only when `R` is required. + """ + T = Array() + safe_call(backend.get().af_qr_inplace(c_pointer(T.arr), A.arr)) + return T
+ +
[docs]def cholesky(A, is_upper=True): + """ + Cholesky decomposition + + Parameters + ---------- + A: af.Array + A 2 dimensional, symmetric, positive definite matrix. + + is_upper: optional: bool. default: True + Specifies if output `R` is upper triangular (if True) or lower triangular (if False). + + Returns + ------- + (R,info): tuple of af.Array, int. + - R - triangular matrix. + - info - 0 if decomposition sucessful. + + Note + ---- + + The original matrix `A` can be reconstructed using the outputs in the following manner. + + >>> A = af.matmulNT(R, R) #if R is upper triangular + + """ + R = Array() + info = c_int_t(0) + safe_call(backend.get().af_cholesky(c_pointer(R.arr), c_pointer(info), A.arr, is_upper)) + return R, info.value
+ +
[docs]def cholesky_inplace(A, is_upper=True): + """ + In place Cholesky decomposition. + + Parameters + ---------- + A: af.Array + - a 2 dimensional, symmetric, positive definite matrix. + - Trinangular matrix on exit. + + is_upper: optional: bool. default: True. + Specifies if output `R` is upper triangular (if True) or lower triangular (if False). + + Returns + ------- + info : int. + 0 if decomposition sucessful. + + """ + info = c_int_t(0) + safe_call(backend.get().af_cholesky_inplace(c_pointer(info), A.arr, is_upper)) + return info.value
+ +
[docs]def solve(A, B, options=MATPROP.NONE): + """ + Solve a system of linear equations. + + Parameters + ---------- + + A: af.Array + A 2 dimensional arrayfire array representing the coefficients of the system. + + B: af.Array + A 1 or 2 dimensional arrayfire array representing the constants of the system. + + options: optional: af.MATPROP. default: af.MATPROP.NONE. + - Additional options to speed up computations. + - Currently needs to be one of `af.MATPROP.NONE`, `af.MATPROP.LOWER`, `af.MATPROP.UPPER`. + + Returns + ------- + X: af.Array + A 1 or 2 dimensional arrayfire array representing the unknowns in the system. + + """ + X = Array() + safe_call(backend.get().af_solve(c_pointer(X.arr), A.arr, B.arr, options.value)) + return X
+ +
[docs]def solve_lu(A, P, B, options=MATPROP.NONE): + """ + Solve a system of linear equations, using LU decomposition. + + Parameters + ---------- + + A: af.Array + - A 2 dimensional arrayfire array representing the coefficients of the system. + - This matrix should be decomposed previously using `lu_inplace(A)`. + + P: af.Array + - Permutation array. + - This array is the output of an earlier call to `lu_inplace(A)` + + B: af.Array + A 1 or 2 dimensional arrayfire array representing the constants of the system. + + Returns + ------- + X: af.Array + A 1 or 2 dimensional arrayfire array representing the unknowns in the system. + + """ + X = Array() + safe_call(backend.get().af_solve_lu(c_pointer(X.arr), A.arr, P.arr, B.arr, options.value)) + return X
+ +
[docs]def inverse(A, options=MATPROP.NONE): + """ + Invert a matrix. + + Parameters + ---------- + + A: af.Array + - A 2 dimensional arrayfire array + + options: optional: af.MATPROP. default: af.MATPROP.NONE. + - Additional options to speed up computations. + - Currently needs to be one of `af.MATPROP.NONE`. + + Returns + ------- + + AI: af.Array + - A 2 dimensional array that is the inverse of `A` + + Note + ---- + + `A` needs to be a square matrix. + + """ + AI = Array() + safe_call(backend.get().af_inverse(c_pointer(AI.arr), A.arr, options.value)) + return AI
+ +
[docs]def pinverse(A, tol=1E-6, options=MATPROP.NONE): + """ + Find pseudo-inverse(Moore-Penrose) of a matrix. + + Parameters + ---------- + + A: af.Array + - A 2 dimensional arrayfire input matrix array + + tol: optional: scalar. default: 1E-6. + - Tolerance for calculating rank + + options: optional: af.MATPROP. default: af.MATPROP.NONE. + - Currently needs to be `af.MATPROP.NONE`. + - Additional options may speed up computation in the future + + Returns + ------- + + AI: af.Array + - A 2 dimensional array that is the pseudo-inverse of `A` + + Note + ---- + + This function is not supported in GFOR + + """ + AI = Array() + safe_call(backend.get().af_pinverse(c_pointer(AI.arr), A.arr, c_double_t(tol), options.value)) + return AI
+ +
[docs]def rank(A, tol=1E-5): + """ + Rank of a matrix. + + Parameters + ---------- + + A: af.Array + - A 2 dimensional arrayfire array + + tol: optional: scalar. default: 1E-5. + - Tolerance for calculating rank + + Returns + ------- + + r: int + - Rank of `A` within the given tolerance + """ + r = c_uint_t(0) + safe_call(backend.get().af_rank(c_pointer(r), A.arr, c_double_t(tol))) + return r.value
+ +
[docs]def det(A): + """ + Determinant of a matrix. + + Parameters + ---------- + + A: af.Array + - A 2 dimensional arrayfire array + + Returns + ------- + + res: scalar + - Determinant of the matrix. + """ + re = c_double_t(0) + im = c_double_t(0) + safe_call(backend.get().af_det(c_pointer(re), c_pointer(im), A.arr)) + re = re.value + im = im.value + return re if (im == 0) else re + im * 1j
+ +
[docs]def norm(A, norm_type=NORM.EUCLID, p=1.0, q=1.0): + """ + Norm of an array or a matrix. + + Parameters + ---------- + + A: af.Array + - A 1 or 2 dimensional arrayfire array + + norm_type: optional: af.NORM. default: af.NORM.EUCLID. + - Type of norm to be calculated. + + p: scalar. default 1.0. + - Used only if `norm_type` is one of `af.NORM.VECTOR_P`, `af.NORM_MATRIX_L_PQ` + + q: scalar. default 1.0. + - Used only if `norm_type` is `af.NORM_MATRIX_L_PQ` + + Returns + ------- + + res: scalar + - norm of the input + + """ + res = c_double_t(0) + safe_call(backend.get().af_norm(c_pointer(res), A.arr, norm_type.value, + c_double_t(p), c_double_t(q))) + return res.value
+ +
[docs]def svd(A): + """ + Singular Value Decomposition + + Parameters + ---------- + A: af.Array + A 2 dimensional arrayfire array. + + Returns + ------- + (U,S,Vt): tuple of af.Arrays + - U - A unitary matrix + - S - An array containing the elements of diagonal matrix + - Vt - A unitary matrix + + Note + ---- + + - The original matrix `A` is preserved and additional storage space is required for decomposition. + + - If the original matrix `A` need not be preserved, use `svd_inplace` instead. + + - The original matrix `A` can be reconstructed using the outputs in the following manner. + >>> Smat = af.diag(S, 0, False) + >>> A_recon = af.matmul(af.matmul(U, Smat), Vt) + + """ + U = Array() + S = Array() + Vt = Array() + safe_call(backend.get().af_svd(c_pointer(U.arr), c_pointer(S.arr), c_pointer(Vt.arr), A.arr)) + return U, S, Vt
+ +
[docs]def svd_inplace(A): + """ + Singular Value Decomposition + + Parameters + ---------- + A: af.Array + A 2 dimensional arrayfire array. + + Returns + ------- + (U,S,Vt): tuple of af.Arrays + - U - A unitary matrix + - S - An array containing the elements of diagonal matrix + - Vt - A unitary matrix + + Note + ---- + + - The original matrix `A` is not preserved. + + - If the original matrix `A` needs to be preserved, use `svd` instead. + + - The original matrix `A` can be reconstructed using the outputs in the following manner. + >>> Smat = af.diag(S, 0, False) + >>> A_recon = af.matmul(af.matmul(U, Smat), Vt) + + """ + U = Array() + S = Array() + Vt = Array() + safe_call(backend.get().af_svd_inplace(c_pointer(U.arr), c_pointer(S.arr), c_pointer(Vt.arr), + A.arr)) + return U, S, Vt
+ +
[docs]def is_lapack_available(): + """ + Function to check if the arrayfire library was built with lapack support. + """ + res = c_bool_t(False) + safe_call(backend.get().af_is_lapack_available(c_pointer(res))) + return res.value
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/library.html b/_modules/arrayfire/library.html new file mode 100644 index 000000000..d6d88b7cf --- /dev/null +++ b/_modules/arrayfire/library.html @@ -0,0 +1,958 @@ + + + + + + + + arrayfire.library — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.library

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Module containing enums and other constants.
+"""
+
+import platform
+import ctypes as ct
+import traceback
+import os
+import sys
+
+c_float_t     = ct.c_float
+c_double_t    = ct.c_double
+c_int_t       = ct.c_int
+c_uint_t      = ct.c_uint
+c_longlong_t  = ct.c_longlong
+c_ulonglong_t = ct.c_ulonglong
+c_char_t      = ct.c_char
+c_bool_t      = ct.c_bool
+c_uchar_t     = ct.c_ubyte
+c_short_t     = ct.c_short
+c_ushort_t    = ct.c_ushort
+c_pointer     = ct.pointer
+c_void_ptr_t  = ct.c_void_p
+c_char_ptr_t  = ct.c_char_p
+c_size_t      = ct.c_size_t
+c_cast        = ct.cast
+
+
[docs]class af_cfloat_t(ct.Structure): + _fields_ = [("real", ct.c_float), ("imag", ct.c_float)]
+ +
[docs]class af_cdouble_t(ct.Structure): + _fields_ = [("real", ct.c_double), ("imag", ct.c_double)]
+ + +AF_VER_MAJOR = '3' +FORGE_VER_MAJOR = '1' + +# Work around for unexpected architectures +if 'c_dim_t_forced' in globals(): + global c_dim_t_forced + c_dim_t = c_dim_t_forced +else: + # dim_t is long long by default + c_dim_t = c_longlong_t + # Change to int for 32 bit x86 and amr architectures + if (platform.architecture()[0][0:2] == '32' and + (platform.machine()[-2:] == '86' or + platform.machine()[0:3] == 'arm')): + c_dim_t = c_int_t + +try: + from enum import Enum as _Enum + def _Enum_Type(v): + return v +except ImportError: + class _MetaEnum(type): + def __init__(cls, name, bases, attrs): + for attrname, attrvalue in attrs.iteritems(): + if name != '_Enum' and isinstance(attrvalue, _Enum_Type): + attrvalue.__class__ = cls + attrs[attrname] = attrvalue + + class _Enum(object): + __metaclass__ = _MetaEnum + + class _Enum_Type(object): + def __init__(self, v): + self.value = v + +
[docs]class ERR(_Enum): + """ + Error values. For internal use only. + """ + + NONE = _Enum_Type(0) + + #100-199 Errors in environment + NO_MEM = _Enum_Type(101) + DRIVER = _Enum_Type(102) + RUNTIME = _Enum_Type(103) + + # 200-299 Errors in input parameters + INVALID_ARRAY = _Enum_Type(201) + ARG = _Enum_Type(202) + SIZE = _Enum_Type(203) + TYPE = _Enum_Type(204) + DIFF_TYPE = _Enum_Type(205) + BATCH = _Enum_Type(207) + DEVICE = _Enum_Type(208) + + # 300-399 Errors for missing software features + NOT_SUPPORTED = _Enum_Type(301) + NOT_CONFIGURED = _Enum_Type(302) + NONFREE = _Enum_Type(303) + + # 400-499 Errors for missing hardware features + NO_DBL = _Enum_Type(401) + NO_GFX = _Enum_Type(402) + NO_HALF = _Enum_Type(403) + + # 500-599 Errors specific to the heterogeneous API + LOAD_LIB = _Enum_Type(501) + LOAD_SYM = _Enum_Type(502) + ARR_BKND_MISMATCH = _Enum_Type(503) + + # 900-999 Errors from upstream libraries and runtimes + INTERNAL = _Enum_Type(998) + UNKNOWN = _Enum_Type(999)
+ +
[docs]class Dtype(_Enum): + """ + Error values. For internal use only. + """ + f32 = _Enum_Type(0) + c32 = _Enum_Type(1) + f64 = _Enum_Type(2) + c64 = _Enum_Type(3) + b8 = _Enum_Type(4) + s32 = _Enum_Type(5) + u32 = _Enum_Type(6) + u8 = _Enum_Type(7) + s64 = _Enum_Type(8) + u64 = _Enum_Type(9) + s16 = _Enum_Type(10) + u16 = _Enum_Type(11) + f16 = _Enum_Type(12)
+ +
[docs]class Source(_Enum): + """ + Source of the pointer + """ + device = _Enum_Type(0) + host = _Enum_Type(1)
+ +
[docs]class INTERP(_Enum): + """ + Interpolation method + """ + NEAREST = _Enum_Type(0) + LINEAR = _Enum_Type(1) + BILINEAR = _Enum_Type(2) + CUBIC = _Enum_Type(3) + LOWER = _Enum_Type(4) + LINEAR_COSINE = _Enum_Type(5) + BILINEAR_COSINE = _Enum_Type(6) + BICUBIC = _Enum_Type(7) + CUBIC_SPLINE = _Enum_Type(8) + BICUBIC_SPLINE = _Enum_Type(9)
+ +
[docs]class PAD(_Enum): + """ + Edge padding types + """ + ZERO = _Enum_Type(0) + SYM = _Enum_Type(1) + CLAMP_TO_EDGE = _Enum_Type(2) + PERIODIC = _Enum_Type(3)
+ +
[docs]class CONNECTIVITY(_Enum): + """ + Neighborhood connectivity + """ + FOUR = _Enum_Type(4) + EIGHT = _Enum_Type(8)
+ +
[docs]class CONV_MODE(_Enum): + """ + Convolution mode + """ + DEFAULT = _Enum_Type(0) + EXPAND = _Enum_Type(1)
+ +
[docs]class CONV_DOMAIN(_Enum): + """ + Convolution domain + """ + AUTO = _Enum_Type(0) + SPATIAL = _Enum_Type(1) + FREQ = _Enum_Type(2)
+ +
[docs]class CONV_GRADIENT(_Enum): + """ + Convolution gradient type + """ + DEFAULT = _Enum_Type(0) + FILTER = _Enum_Type(1) + DATA = _Enum_Type(2) + BIAS = _Enum_Type(3)
+ +
[docs]class MATCH(_Enum): + """ + Match type + """ + + """ + Sum of absolute differences + """ + SAD = _Enum_Type(0) + + """ + Zero mean SAD + """ + ZSAD = _Enum_Type(1) + + """ + Locally scaled SAD + """ + LSAD = _Enum_Type(2) + + """ + Sum of squared differences + """ + SSD = _Enum_Type(3) + + """ + Zero mean SSD + """ + ZSSD = _Enum_Type(4) + + """ + Locally scaled SSD + """ + LSSD = _Enum_Type(5) + + """ + Normalized cross correlation + """ + NCC = _Enum_Type(6) + + """ + Zero mean NCC + """ + ZNCC = _Enum_Type(7) + + """ + Sum of hamming distances + """ + SHD = _Enum_Type(8)
+ + +
[docs]class YCC_STD(_Enum): + """ + YCC Standard formats + """ + BT_601 = _Enum_Type(601) + BT_709 = _Enum_Type(709) + BT_2020 = _Enum_Type(2020)
+ +
[docs]class CSPACE(_Enum): + """ + Colorspace formats + """ + GRAY = _Enum_Type(0) + RGB = _Enum_Type(1) + HSV = _Enum_Type(2) + YCbCr= _Enum_Type(3)
+ +
[docs]class MATPROP(_Enum): + """ + Matrix properties + """ + + """ + None, general. + """ + NONE = _Enum_Type(0) + + """ + Transposed. + """ + TRANS = _Enum_Type(1) + + """ + Conjugate transposed. + """ + CTRANS = _Enum_Type(2) + + """ + Upper triangular matrix. + """ + UPPER = _Enum_Type(32) + + """ + Lower triangular matrix. + """ + LOWER = _Enum_Type(64) + + """ + Treat diagonal as units. + """ + DIAG_UNIT = _Enum_Type(128) + + """ + Symmetric matrix. + """ + SYM = _Enum_Type(512) + + """ + Positive definite matrix. + """ + POSDEF = _Enum_Type(1024) + + """ + Orthogonal matrix. + """ + ORTHOG = _Enum_Type(2048) + + """ + Tri diagonal matrix. + """ + TRI_DIAG = _Enum_Type(4096) + + """ + Block diagonal matrix. + """ + BLOCK_DIAG = _Enum_Type(8192)
+ +
[docs]class NORM(_Enum): + """ + Norm types + """ + VECTOR_1 = _Enum_Type(0) + VECTOR_INF = _Enum_Type(1) + VECTOR_2 = _Enum_Type(2) + VECTOR_P = _Enum_Type(3) + MATRIX_1 = _Enum_Type(4) + MATRIX_INF = _Enum_Type(5) + MATRIX_2 = _Enum_Type(6) + MATRIX_L_PQ = _Enum_Type(7) + EUCLID = VECTOR_2
+ +
[docs]class COLORMAP(_Enum): + """ + Colormaps + """ + DEFAULT = _Enum_Type(0) + SPECTRUM = _Enum_Type(1) + COLORS = _Enum_Type(2) + RED = _Enum_Type(3) + MOOD = _Enum_Type(4) + HEAT = _Enum_Type(5) + BLUE = _Enum_Type(6)
+ +
[docs]class IMAGE_FORMAT(_Enum): + """ + Image Formats + """ + BMP = _Enum_Type(0) + ICO = _Enum_Type(1) + JPEG = _Enum_Type(2) + JNG = _Enum_Type(3) + PNG = _Enum_Type(13) + PPM = _Enum_Type(14) + PPMRAW = _Enum_Type(15) + TIFF = _Enum_Type(18) + PSD = _Enum_Type(20) + HDR = _Enum_Type(26) + EXR = _Enum_Type(29) + JP2 = _Enum_Type(31) + RAW = _Enum_Type(34)
+ +
[docs]class HOMOGRAPHY(_Enum): + """ + Homography Types + """ + RANSAC = _Enum_Type(0) + LMEDS = _Enum_Type(1)
+ +
[docs]class BACKEND(_Enum): + """ + Backend libraries + """ + DEFAULT = _Enum_Type(0) + CPU = _Enum_Type(1) + CUDA = _Enum_Type(2) + OPENCL = _Enum_Type(4)
+ +
[docs]class MARKER(_Enum): + """ + Markers used for different points in graphics plots + """ + NONE = _Enum_Type(0) + POINT = _Enum_Type(1) + CIRCLE = _Enum_Type(2) + SQUARE = _Enum_Type(3) + TRIANGE = _Enum_Type(4) + CROSS = _Enum_Type(5) + PLUS = _Enum_Type(6) + STAR = _Enum_Type(7)
+ +
[docs]class MOMENT(_Enum): + """ + Image Moments types + """ + M00 = _Enum_Type(1) + M01 = _Enum_Type(2) + M10 = _Enum_Type(4) + M11 = _Enum_Type(8) + FIRST_ORDER = _Enum_Type(15)
+ +
[docs]class BINARYOP(_Enum): + """ + Binary Operators + """ + ADD = _Enum_Type(0) + MUL = _Enum_Type(1) + MIN = _Enum_Type(2) + MAX = _Enum_Type(3)
+ +
[docs]class RANDOM_ENGINE(_Enum): + """ + Random engine types + """ + PHILOX_4X32_10 = _Enum_Type(100) + THREEFRY_2X32_16 = _Enum_Type(200) + MERSENNE_GP11213 = _Enum_Type(300) + PHILOX = PHILOX_4X32_10 + THREEFRY = THREEFRY_2X32_16 + DEFAULT = PHILOX
+ +
[docs]class STORAGE(_Enum): + """ + Matrix Storage types + """ + DENSE = _Enum_Type(0) + CSR = _Enum_Type(1) + CSC = _Enum_Type(2) + COO = _Enum_Type(3)
+ +
[docs]class CANNY_THRESHOLD(_Enum): + """ + Canny Edge Threshold types + """ + MANUAL = _Enum_Type(0) + AUTO_OTSU = _Enum_Type(1)
+ +
[docs]class FLUX(_Enum): + """ + Flux functions + """ + DEFAULT = _Enum_Type(0) + QUADRATIC = _Enum_Type(1) + EXPONENTIAL = _Enum_Type(2)
+ +
[docs]class DIFFUSION(_Enum): + """ + Diffusion equations + """ + DEFAULT = _Enum_Type(0) + GRAD = _Enum_Type(1) + MCDE = _Enum_Type(2)
+ +
[docs]class TOPK(_Enum): + """ + Top-K ordering + """ + DEFAULT = _Enum_Type(0) + MIN = _Enum_Type(1) + MAX = _Enum_Type(2)
+ +
[docs]class ITERATIVE_DECONV(_Enum): + """ + Iterative deconvolution algorithm + """ + DEFAULT = _Enum_Type(0) + LANDWEBER = _Enum_Type(1) + RICHARDSONLUCY = _Enum_Type(2)
+ +
[docs]class INVERSE_DECONV(_Enum): + """ + Inverse deconvolution algorithm + """ + DEFAULT = _Enum_Type(0) + TIKHONOV = _Enum_Type(1)
+ +
[docs]class VARIANCE(_Enum): + """ + Variance bias type + """ + DEFAULT = _Enum_Type(0) + SAMPLE = _Enum_Type(1) + POPULATION = _Enum_Type(2)
+ +_VER_MAJOR_PLACEHOLDER = "__VER_MAJOR__" + +def _setup(): + platform_name = platform.system() + + try: + AF_PATH = os.environ['AF_PATH'] + except KeyError: + AF_PATH = None + pass + + AF_SEARCH_PATH = AF_PATH + + try: + CUDA_PATH = os.environ['CUDA_PATH'] + except KeyError: + CUDA_PATH= None + pass + + CUDA_FOUND = False + + assert(len(platform_name) >= 3) + if platform_name == 'Windows' or platform_name[:3] == 'CYG': + + ## Windows specific setup + pre = '' + post = '.dll' + if platform_name == "Windows": + ''' + Supressing crashes caused by missing dlls + http://stackoverflow.com/questions/8347266/missing-dll-print-message-instead-of-launching-a-popup + https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx + ''' + ct.windll.kernel32.SetErrorMode(0x0001 | 0x0002) + + if AF_SEARCH_PATH is None: + AF_SEARCH_PATH = "C:/Program Files/ArrayFire/v" + AF_VER_MAJOR +"/" + + if CUDA_PATH is not None: + CUDA_FOUND = os.path.isdir(CUDA_PATH + '/bin') and os.path.isdir(CUDA_PATH + '/nvvm/bin/') + + elif platform_name == 'Darwin': + + ## OSX specific setup + pre = 'lib' + post = '.' + _VER_MAJOR_PLACEHOLDER + '.dylib' + + if AF_SEARCH_PATH is None: + if os.path.exists('/opt/arrayfire'): + AF_SEARCH_PATH = '/opt/arrayfire/' + else: + AF_SEARCH_PATH = '/usr/local/' + + if CUDA_PATH is None: + CUDA_PATH='/usr/local/cuda/' + + CUDA_FOUND = os.path.isdir(CUDA_PATH + '/lib') and os.path.isdir(CUDA_PATH + '/nvvm/lib') + + elif platform_name == 'Linux': + pre = 'lib' + post = '.so.' + _VER_MAJOR_PLACEHOLDER + + if AF_SEARCH_PATH is None: + if os.path.exists('/opt/arrayfire-' + AF_VER_MAJOR + '/'): + AF_SEARCH_PATH = '/opt/arrayfire-' + AF_VER_MAJOR + '/' + elif os.path.exists('/opt/arrayfire/'): + AF_SEARCH_PATH = '/opt/arrayfire/' + else: + AF_SEARCH_PATH = '/usr/local/' + + if CUDA_PATH is None: + CUDA_PATH='/usr/local/cuda/' + + if platform.architecture()[0][:2] == '64': + CUDA_FOUND = os.path.isdir(CUDA_PATH + '/lib64') and os.path.isdir(CUDA_PATH + '/nvvm/lib64') + else: + CUDA_FOUND = os.path.isdir(CUDA_PATH + '/lib') and os.path.isdir(CUDA_PATH + '/nvvm/lib') + else: + raise OSError(platform_name + ' not supported') + + return pre, post, AF_PATH, AF_SEARCH_PATH, CUDA_FOUND + +class _clibrary(object): + + def __find_nvrtc_builtins_libname(self, search_path): + filelist = os.listdir(search_path) + for f in filelist: + if 'nvrtc-builtins' in f: + return f + return None + + def __libname(self, name, head='af', ver_major=AF_VER_MAJOR): + post = self.__post.replace(_VER_MAJOR_PLACEHOLDER, ver_major) + libname = self.__pre + head + name + post + + if self.AF_PATH: + if os.path.isdir(self.AF_PATH + '/lib64'): + path_search = self.AF_PATH + '/lib64/' + else: + path_search = self.AF_PATH + '/lib/' + else: + if os.path.isdir(self.AF_SEARCH_PATH + '/lib64'): + path_search = self.AF_SEARCH_PATH + '/lib64/' + else: + path_search = self.AF_SEARCH_PATH + '/lib/' + + if platform.architecture()[0][:2] == '64': + path_site = sys.prefix + '/lib64/' + else: + path_site = sys.prefix + '/lib/' + + path_local = self.AF_PYMODULE_PATH + libpaths = [('', libname), + (path_site, libname), + (path_local,libname)] + if self.AF_PATH: #prefer specified AF_PATH if exists + libpaths.append((path_search, libname)) + else: + libpaths.insert(2, (path_search, libname)) + return libpaths + + def set_unsafe(self, name): + lib = self.__clibs[name] + if (lib is None): + raise RuntimeError("Backend not found") + self.__name = name + + def __init__(self): + + more_info_str = "Please look at https://github.com/arrayfire/arrayfire-python/wiki for more information." + + pre, post, AF_PATH, AF_SEARCH_PATH, CUDA_FOUND = _setup() + + self.__pre = pre + self.__post = post + self.AF_PATH = AF_PATH + self.AF_SEARCH_PATH = AF_SEARCH_PATH + self.CUDA_FOUND = CUDA_FOUND + + # prefer locally packaged arrayfire libraries if they exist + af_module = __import__(__name__) + self.AF_PYMODULE_PATH = af_module.__path__[0] + '/' if af_module.__path__ else None + + + self.__name = None + + self.__clibs = {'cuda' : None, + 'opencl' : None, + 'cpu' : None, + 'unified' : None} + + self.__backend_map = {0 : 'unified', + 1 : 'cpu' , + 2 : 'cuda' , + 4 : 'opencl' } + + self.__backend_name_map = {'default' : 0, + 'unified' : 0, + 'cpu' : 1, + 'cuda' : 2, + 'opencl' : 4} + + # Try to pre-load forge library if it exists + libnames = reversed(self.__libname('forge', head='', ver_major=FORGE_VER_MAJOR)) + + try: + VERBOSE_LOADS = os.environ['AF_VERBOSE_LOADS'] == '1' + except KeyError: + VERBOSE_LOADS = False + pass + + for libname in libnames: + try: + full_libname = libname[0] + libname[1] + ct.cdll.LoadLibrary(full_libname) + if VERBOSE_LOADS: + print('Loaded ' + full_libname) + break + except OSError: + if VERBOSE_LOADS: + traceback.print_exc() + print('Unable to load ' + full_libname) + pass + + c_dim4 = c_dim_t*4 + out = c_void_ptr_t(0) + dims = c_dim4(10, 10, 1, 1) + + # Iterate in reverse order of preference + for name in ('cpu', 'opencl', 'cuda', ''): + libnames = reversed(self.__libname(name)) + for libname in libnames: + try: + full_libname = libname[0] + libname[1] + + ct.cdll.LoadLibrary(full_libname) + __name = 'unified' if name == '' else name + clib = ct.CDLL(full_libname) + self.__clibs[__name] = clib + err = clib.af_randu(c_pointer(out), 4, c_pointer(dims), Dtype.f32.value) + if (err == ERR.NONE.value): + self.__name = __name + clib.af_release_array(out) + if VERBOSE_LOADS: + print('Loaded ' + full_libname) + + # load nvrtc-builtins library if using cuda + if name == 'cuda': + nvrtc_name = self.__find_nvrtc_builtins_libname(libname[0]) + if nvrtc_name: + ct.cdll.LoadLibrary(libname[0] + nvrtc_name) + + if VERBOSE_LOADS: + print('Loaded ' + libname[0] + nvrtc_name) + else: + if VERBOSE_LOADS: + print('Could not find local nvrtc-builtins libarary') + + break; + except OSError: + if VERBOSE_LOADS: + traceback.print_exc() + print('Unable to load ' + full_libname) + pass + + if (self.__name is None): + raise RuntimeError("Could not load any ArrayFire libraries.\n" + more_info_str) + + def get_id(self, name): + return self.__backend_name_map[name] + + def get_name(self, bk_id): + return self.__backend_map[bk_id] + + def get(self): + return self.__clibs[self.__name] + + def name(self): + return self.__name + + def is_unified(self): + return self.__name == 'unified' + + def parse(self, res): + lst = [] + for key,value in self.__backend_name_map.items(): + if (value & res): + lst.append(key) + return tuple(lst) + + +backend = _clibrary() + +
[docs]def set_backend(name, unsafe=False): + """ + Set a specific backend by name + + Parameters + ---------- + + name : str. + + unsafe : optional: bool. Default: False. + If False, does not switch backend if current backend is not unified backend. + """ + if (backend.is_unified() == False and unsafe == False): + raise RuntimeError("Can not change backend to %s after loading %s" % (name, backend.name())) + + if (backend.is_unified()): + safe_call(backend.get().af_set_backend(backend.get_id(name))) + else: + backend.set_unsafe(name) + return
+ +
[docs]def get_backend(): + """ + Return the name of the backend + """ + return backend.name()
+ +
[docs]def get_backend_id(A): + """ + Get backend name of an array + + Parameters + ---------- + A : af.Array + + Returns + ---------- + + name : str. + Backend name + """ + backend_id = c_int_t(BACKEND.CPU.value) + safe_call(backend.get().af_get_backend_id(c_pointer(backend_id), A.arr)) + return backend.get_name(backend_id.value)
+ +
[docs]def get_backend_count(): + """ + Get number of available backends + + Returns + ---------- + + count : int + Number of available backends + """ + count = c_int_t(0) + safe_call(backend.get().af_get_backend_count(c_pointer(count))) + return count.value
+ +
[docs]def get_available_backends(): + """ + Get names of available backends + + Returns + ---------- + + names : tuple of strings + Names of available backends + """ + available = c_int_t(0) + safe_call(backend.get().af_get_available_backends(c_pointer(available))) + return backend.parse(int(available.value))
+ +
[docs]def get_active_backend(): + """ + Get the current active backend + + name : str. + Backend name + """ + backend_id = c_int_t(BACKEND.CPU.value) + safe_call(backend.get().af_get_active_backend(c_pointer(backend_id))) + return backend.get_name(backend_id.value)
+ +
[docs]def get_device_id(A): + """ + Get the device id of the array + + Parameters + ---------- + A : af.Array + + Returns + ---------- + + dev : Integer + id of the device array was created on + """ + device_id = c_int_t(0) + safe_call(backend.get().af_get_device_id(c_pointer(device_id), A.arr)) + return device_id
+ +
[docs]def get_size_of(dtype): + """ + Get the size of the type represented by arrayfire.Dtype + """ + size = c_size_t(0) + safe_call(backend.get().af_get_size_of(c_pointer(size), dtype.value)) + return size.value
+ +from .util import safe_call +
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/opencl.html b/_modules/arrayfire/opencl.html new file mode 100644 index 000000000..351b30db0 --- /dev/null +++ b/_modules/arrayfire/opencl.html @@ -0,0 +1,345 @@ + + + + + + + + arrayfire.opencl — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.opencl

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Functions specific to OpenCL backend.
+
+This module provides interoperability with other OpenCL libraries.
+"""
+
+from .util import *
+from .library import (_Enum, _Enum_Type)
+
+
[docs]class DEVICE_TYPE(_Enum): + """ + ArrayFire wrapper for CL_DEVICE_TYPE + """ + CPU = _Enum_Type(1<<1) + GPU = _Enum_Type(1<<2) + ACC = _Enum_Type(1<<3) + UNKNOWN = _Enum_Type(-1)
+ +
[docs]class PLATFORM(_Enum): + """ + ArrayFire enum for common platforms + """ + AMD = _Enum_Type(0) + APPLE = _Enum_Type(1) + INTEL = _Enum_Type(2) + NVIDIA = _Enum_Type(3) + BEIGNET = _Enum_Type(4) + POCL = _Enum_Type(5) + UNKNOWN = _Enum_Type(-1)
+ +
[docs]def get_context(retain=False): + """ + Get the current OpenCL context being used by ArrayFire. + + Parameters + ---------- + + retain : bool. optional. Default: False. + Specifies if the context needs to be retained by arrayfire before returning. + + Returns + ----------- + context : integer denoting the context id. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + context = c_void_ptr_t(0) + safe_call(backend.get().afcl_get_context(c_pointer(context), retain)) + return context.value
+ +
[docs]def get_queue(retain): + """ + Get the current OpenCL command queue being used by ArrayFire. + + Parameters + ---------- + + retain : bool. optional. Default: False. + Specifies if the context needs to be retained by arrayfire before returning. + + Returns + ----------- + queue : integer denoting the queue id. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + queue = c_int_t(0) + safe_call(backend.get().afcl_get_queue(c_pointer(queue), retain)) + return queue.value
+ +
[docs]def get_device_id(): + """ + Get native (unsorted) OpenCL device ID + + Returns + -------- + + idx : int. + Specifies the `cl_device_id` of the device. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + idx = c_int_t(0) + safe_call(backend.get().afcl_get_device_id(c_pointer(idx))) + return idx.value
+ +
[docs]def set_device_id(idx): + """ + Set native (unsorted) OpenCL device ID + + Parameters + ---------- + + idx : int. + Specifies the `cl_device_id` of the device. + """ + + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + safe_call(backend.get().afcl_set_device_id(idx)) + return
+ +
[docs]def add_device_context(dev, ctx, que): + """ + Add a new device to arrayfire opencl device manager + + Parameters + ---------- + + dev : cl_device_id + + ctx : cl_context + + que : cl_command_queue + + """ + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + safe_call(backend.get().afcl_add_device_context(dev, ctx, que))
+ +
[docs]def set_device_context(dev, ctx): + """ + Set a device as current active device + + Parameters + ---------- + + dev : cl_device_id + + ctx : cl_context + + """ + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + safe_call(backend.get().afcl_set_device_context(dev, ctx))
+ +
[docs]def delete_device_context(dev, ctx): + """ + Delete a device + + Parameters + ---------- + + dev : cl_device_id + + ctx : cl_context + + """ + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + safe_call(backend.get().afcl_delete_device_context(dev, ctx))
+ + +_to_device_type = {DEVICE_TYPE.CPU.value : DEVICE_TYPE.CPU, + DEVICE_TYPE.GPU.value : DEVICE_TYPE.GPU, + DEVICE_TYPE.ACC.value : DEVICE_TYPE.ACC, + DEVICE_TYPE.UNKNOWN.value : DEVICE_TYPE.UNKNOWN} + +_to_platform = {PLATFORM.AMD.value : PLATFORM.AMD, + PLATFORM.APPLE.value : PLATFORM.APPLE, + PLATFORM.INTEL.value : PLATFORM.INTEL, + PLATFORM.NVIDIA.value : PLATFORM.NVIDIA, + PLATFORM.BEIGNET.value : PLATFORM.BEIGNET, + PLATFORM.POCL.value : PLATFORM.POCL, + PLATFORM.UNKNOWN.value : PLATFORM.UNKNOWN} + + +
[docs]def get_device_type(): + """ + Get opencl device type + """ + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + res = c_int_t(DEVICE_TYPE.UNKNOWN.value) + safe_call(backend.get().afcl_get_device_type(c_pointer(res))) + return _to_device_type[res.value]
+ +
[docs]def get_platform(): + """ + Get opencl platform + """ + import ctypes as ct + from .util import safe_call as safe_call + from .library import backend + + if (backend.name() != "opencl"): + raise RuntimeError("Invalid backend loaded") + + res = c_int_t(PLATFORM.UNKNOWN.value) + safe_call(backend.get().afcl_get_platform(c_pointer(res))) + return _to_platform[res.value]
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/random.html b/_modules/arrayfire/random.html new file mode 100644 index 000000000..e89335e3d --- /dev/null +++ b/_modules/arrayfire/random.html @@ -0,0 +1,334 @@ + + + + + + + + arrayfire.random — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.random

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Random engine class and functions to generate random numbers.
+"""
+
+from .library import *
+from .array import *
+import numbers
+
+
[docs]class Random_Engine(object): + """ + Class to handle random number generator engines. + + Parameters + ---------- + + engine_type : optional: RANDOME_ENGINE. default: RANDOM_ENGINE.PHILOX + - Specifies the type of random engine to be created. Can be one of: + - RANDOM_ENGINE.PHILOX_4X32_10 + - RANDOM_ENGINE.THREEFRY_2X32_16 + - RANDOM_ENGINE.MERSENNE_GP11213 + - RANDOM_ENGINE.PHILOX (same as RANDOM_ENGINE.PHILOX_4X32_10) + - RANDOM_ENGINE.THREEFRY (same as RANDOM_ENGINE.THREEFRY_2X32_16) + - RANDOM_ENGINE.DEFAULT + - Not used if engine is not None + + seed : optional int. default: 0 + - Specifies the seed for the random engine + - Not used if engine is not None + + engine : optional ctypes.c_void_p. default: None. + - Used a handle created by the C api to create the Random_Engine. + """ + + def __init__(self, engine_type = RANDOM_ENGINE.PHILOX, seed = 0, engine = None): + if (engine is None): + self.engine = c_void_ptr_t(0) + safe_call(backend.get().af_create_random_engine(c_pointer(self.engine), engine_type.value, c_longlong_t(seed))) + else: + self.engine = engine + + def __del__(self): + safe_call(backend.get().af_release_random_engine(self.engine)) + +
[docs] def set_type(self, engine_type): + """ + Set the type of the random engine. + """ + safe_call(backend.get().af_random_engine_set_type(c_pointer(self.engine), engine_type.value))
+ +
[docs] def get_type(self): + """ + Get the type of the random engine. + """ + __to_random_engine_type = [RANDOM_ENGINE.PHILOX_4X32_10, + RANDOM_ENGINE.THREEFRY_2X32_16, + RANDOM_ENGINE.MERSENNE_GP11213] + rty = c_int_t(RANDOM_ENGINE.PHILOX.value) + safe_call(backend.get().af_random_engine_get_type(c_pointer(rty), self.engine)) + return __to_random_engine_type[rty]
+ +
[docs] def set_seed(self, seed): + """ + Set the seed for the random engine. + """ + safe_call(backend.get().af_random_engine_set_seed(c_pointer(self.engine), c_longlong_t(seed)))
+ +
[docs] def get_seed(self): + """ + Get the seed for the random engine. + """ + seed = c_longlong_t(0) + safe_call(backend.get().af_random_engine_get_seed(c_pointer(seed), self.engine)) + return seed.value
+ +
[docs]def randu(d0, d1=None, d2=None, d3=None, dtype=Dtype.f32, engine=None): + """ + Create a multi dimensional array containing values from a uniform distribution. + + Parameters + ---------- + d0 : int. + Length of first dimension. + + d1 : optional: int. default: None. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + engine : optional: Random_Engine. default: None. + If engine is None, uses a default engine created by arrayfire. + + Returns + ------- + + out : af.Array + Multi dimensional array whose elements are sampled uniformly between [0, 1]. + - If d1 is None, `out` is 1D of size (d0,). + - If d1 is not None and d2 is None, `out` is 2D of size (d0, d1). + - If d1 and d2 are not None and d3 is None, `out` is 3D of size (d0, d1, d2). + - If d1, d2, d3 are all not None, `out` is 4D of size (d0, d1, d2, d3). + """ + out = Array() + dims = dim4(d0, d1, d2, d3) + + if engine is None: + safe_call(backend.get().af_randu(c_pointer(out.arr), 4, c_pointer(dims), dtype.value)) + else: + safe_call(backend.get().af_random_uniform(c_pointer(out.arr), 4, c_pointer(dims), dtype.value, engine.engine)) + + return out
+ +
[docs]def randn(d0, d1=None, d2=None, d3=None, dtype=Dtype.f32, engine=None): + """ + Create a multi dimensional array containing values from a normal distribution. + + Parameters + ---------- + d0 : int. + Length of first dimension. + + d1 : optional: int. default: None. + Length of second dimension. + + d2 : optional: int. default: None. + Length of third dimension. + + d3 : optional: int. default: None. + Length of fourth dimension. + + dtype : optional: af.Dtype. default: af.Dtype.f32. + Data type of the array. + + engine : optional: Random_Engine. default: None. + If engine is None, uses a default engine created by arrayfire. + + Returns + ------- + + out : af.Array + Multi dimensional array whose elements are sampled from a normal distribution with mean 0 and sigma of 1. + - If d1 is None, `out` is 1D of size (d0,). + - If d1 is not None and d2 is None, `out` is 2D of size (d0, d1). + - If d1 and d2 are not None and d3 is None, `out` is 3D of size (d0, d1, d2). + - If d1, d2, d3 are all not None, `out` is 4D of size (d0, d1, d2, d3). + """ + + out = Array() + dims = dim4(d0, d1, d2, d3) + + if engine is None: + safe_call(backend.get().af_randn(c_pointer(out.arr), 4, c_pointer(dims), dtype.value)) + else: + safe_call(backend.get().af_random_normal(c_pointer(out.arr), 4, c_pointer(dims), dtype.value, engine.engine)) + + return out
+ +
[docs]def set_seed(seed=0): + """ + Set the seed for the random number generator. + + Parameters + ---------- + seed: int. + Seed for the random number generator + """ + safe_call(backend.get().af_set_seed(c_ulonglong_t(seed)))
+ +
[docs]def get_seed(): + """ + Get the seed for the random number generator. + + Returns + ------- + seed: int. + Seed for the random number generator + """ + seed = c_ulonglong_t(0) + safe_call(backend.get().af_get_seed(c_pointer(seed))) + return seed.value
+ +
[docs]def set_default_random_engine_type(engine_type): + """ + Set random engine type for default random engine. + + Parameters + ---------- + engine_type : RANDOME_ENGINE. + - Specifies the type of random engine to be created. Can be one of: + - RANDOM_ENGINE.PHILOX_4X32_10 + - RANDOM_ENGINE.THREEFRY_2X32_16 + - RANDOM_ENGINE.MERSENNE_GP11213 + - RANDOM_ENGINE.PHILOX (same as RANDOM_ENGINE.PHILOX_4X32_10) + - RANDOM_ENGINE.THREEFRY (same as RANDOM_ENGINE.THREEFRY_2X32_16) + - RANDOM_ENGINE.DEFAULT + + Note + ---- + + This only affects randu and randn when a random engine is not specified. + """ + safe_call(backend.get().af_set_default_random_engine_type(c_pointer(self.engine), engine_type.value))
+ +
[docs]def get_default_random_engine(): + """ + Get the default random engine + + Returns + ------- + + The default random engine used by randu and randn + """ + engine = c_void_ptr_t(0) + default_engine = c_void_ptr_t(0) + safe_call(backend.get().af_get_default_random_engine(c_pointer(default_engine))) + safe_call(backend.get().af_retain_random_engine(c_pointer(engine), default_engine)) + return Random_Engine(engine=engine)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/signal.html b/_modules/arrayfire/signal.html new file mode 100644 index 000000000..5db7f6d66 --- /dev/null +++ b/_modules/arrayfire/signal.html @@ -0,0 +1,1736 @@ + + + + + + + + arrayfire.signal — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.signal

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Signal processing functions (fft, convolve, etc).
+"""
+
+from .library import *
+from .array import *
+from .bcast import broadcast
+
+@broadcast
+def _scale_pos_axis0(x_curr, x_orig):
+    x0 = x_orig[0, 0, 0, 0]
+    dx = x_orig[1, 0, 0, 0] - x0
+    return((x_curr - x0) / dx)
+
+@broadcast
+def _scale_pos_axis1(y_curr, y_orig):
+    y0 = y_orig[0, 0, 0, 0]
+    dy = y_orig[0, 1, 0, 0] - y0
+    return((y_curr - y0) / dy)
+
+
[docs]def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp = None, output = None): + """ + Interpolate along a single dimension.Interpolation is performed along axis 0 + of the input array. + + Parameters + ---------- + + signal: af.Array + Input signal array (signal = f(x)) + + x: af.Array + The x-coordinates of the interpolation points. The interpolation + function is queried at these set of points. + + method: optional: af.INTERP. default: af.INTERP.LINEAR. + Interpolation method. + + off_grid: optional: scalar. default: 0.0. + The value used for positions outside the range. + + xp : af.Array + The x-coordinates of the input data points + + output: None or af.Array + Optional preallocated output array. If it is a sub-array of an existing af_array, + only the corresponding portion of the af_array will be overwritten + + Returns + ------- + + output: af.Array + Values calculated at interpolation points. + + + Note + ----- + This holds applicable when x_input isn't provided: + The initial measurements are assumed to have taken place at equal steps between [0, N - 1], + where N is the length of the first dimension of `signal`. + """ + + if output is None: + output = Array() + + if(xp is not None): + pos0 = _scale_pos_axis0(x, xp) + else: + pos0 = x + + safe_call(backend.get().af_approx1(c_pointer(output.arr), signal.arr, pos0.arr, + method.value, c_float_t(off_grid))) + + else: + if(xp is not None): + pos0 = _scale_pos_axis0(x, xp) + else: + pos0 = x + safe_call(backend.get().af_approx1_v2(c_pointer(output.arr), signal.arr, pos0.arr, + method.value, c_float_t(off_grid))) + return output
+ + +
[docs]def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LINEAR, off_grid=0.0, output = None): + """ + Interpolation on one dimensional signals along specified dimension. + + af_approx1_uniform() accepts the dimension to perform the interpolation along the input. + It also accepts start and step values which define the uniform range of corresponding indices. + + Parameters + ---------- + + signal: af.Array + Input signal array (signal = f(x)) + + x: af.Array + The x-coordinates of the interpolation points. The interpolation + function is queried at these set of points. + + interp_dim: scalar + is the dimension to perform interpolation across. + + idx_start: scalar + is the first index value along interp_dim. + + idx_step: scalar + is the uniform spacing value between subsequent indices along interp_dim. + + method: optional: af.INTERP. default: af.INTERP.LINEAR. + Interpolation method. + + off_grid: optional: scalar. default: 0.0. + The value used for positions outside the range. + + output: None or af.Array + Optional preallocated output array. If it is a sub-array of an existing af_array, + only the corresponding portion of the af_array will be overwritten + + Returns + ------- + + output: af.Array + Values calculated at interpolation points. + + """ + + if output is None: + output = Array() + + safe_call(backend.get().af_approx1_uniform(c_pointer(output.arr), signal.arr, x.arr, + c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), + method.value, c_float_t(off_grid))) + else: + safe_call(backend.get().af_approx1_uniform_v2(c_pointer(output.arr), signal.arr, x.arr, + c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), + method.value, c_float_t(off_grid))) + return output
+ + +
[docs]def approx2(signal, x, y, + method=INTERP.LINEAR, off_grid=0.0, xp = None, yp = None, output = None): + """ + Interpolate along a two dimension.Interpolation is performed along axes 0 and 1 + of the input array. + + Parameters + ---------- + + signal: af.Array + Input signal array (signal = f(x, y)) + + x : af.Array + The x-coordinates of the interpolation points. The interpolation + function is queried at these set of points. + + + y : af.Array + The y-coordinates of the interpolation points. The interpolation + function is queried at these set of points. + + method: optional: af.INTERP. default: af.INTERP.LINEAR. + Interpolation method. + + off_grid: optional: scalar. default: 0.0. + The value used for positions outside the range. + + xp : af.Array + The x-coordinates of the input data points. The convention followed is that + the x-coordinates vary along axis 0 + + yp : af.Array + The y-coordinates of the input data points. The convention followed is that + the y-coordinates vary along axis 1 + + output: None or af.Array + Optional preallocated output array. If it is a sub-array of an existing af_array, + only the corresponding portion of the af_array will be overwritten + + Returns + ------- + + output: af.Array + Values calculated at interpolation points. + + Note + ----- + This holds applicable when x_input/y_input isn't provided: + + The initial measurements are assumed to have taken place at equal steps between [(0,0) - [M - 1, N - 1]] + where M is the length of the first dimension of `signal`, + and N is the length of the second dimension of `signal`. + """ + + if output is None: + output = Array() + + if(xp is not None): + pos0 = _scale_pos_axis0(x, xp) + else: + pos0 = x + + if(yp is not None): + pos1 = _scale_pos_axis1(y, yp) + else: + pos1 = y + + safe_call(backend.get().af_approx2(c_pointer(output.arr), signal.arr, + pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) + else: + if(xp is not None): + pos0 = _scale_pos_axis0(x, xp) + else: + pos0 = x + + if(yp is not None): + pos1 = _scale_pos_axis1(y, yp) + else: + pos1 = y + + safe_call(backend.get().af_approx2_v2(c_pointer(output.arr), signal.arr, + pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) + + return output
+ +
[docs]def approx2_uniform(signal, pos0, interp_dim0, idx_start0, idx_step0, pos1, interp_dim1, idx_start1, idx_step1, + method=INTERP.LINEAR, off_grid=0.0, output = None): + """ + Interpolate along two uniformly spaced dimensions of the input array. + af_approx2_uniform() accepts two dimensions to perform the interpolation along the input. + It also accepts start and step values which define the uniform range of corresponding indices. + + Parameters + ---------- + + signal: af.Array + Input signal array (signal = f(x, y)) + + pos0 : af.Array + positions of the interpolation points along interp_dim0. + + interp_dim0: scalar + is the first dimension to perform interpolation across. + + idx_start0: scalar + is the first index value along interp_dim0. + + idx_step0: scalar + is the uniform spacing value between subsequent indices along interp_dim0. + + pos1 : af.Array + positions of the interpolation points along interp_dim1. + + interp_dim1: scalar + is the second dimension to perform interpolation across. + + idx_start1: scalar + is the first index value along interp_dim1. + + idx_step1: scalar + is the uniform spacing value between subsequent indices along interp_dim1. + + method: optional: af.INTERP. default: af.INTERP.LINEAR. + Interpolation method. + + off_grid: optional: scalar. default: 0.0. + The value used for positions outside the range. + + output: None or af.Array + Optional preallocated output array. If it is a sub-array of an existing af_array, + only the corresponding portion of the af_array will be overwritten + + Returns + ------- + + output: af.Array + Values calculated at interpolation points. + + Note + ----- + This holds applicable when x_input/y_input isn't provided: + + The initial measurements are assumed to have taken place at equal steps between [(0,0) - [M - 1, N - 1]] + where M is the length of the first dimension of `signal`, + and N is the length of the second dimension of `signal`. + """ + + if output is None: + output = Array() + safe_call(backend.get().af_approx2_uniform(c_pointer(output.arr), signal.arr, + pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), c_double_t(idx_step0), + pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), + method.value, c_float_t(off_grid))) + else: + safe_call(backend.get().af_approx2_uniform_v2(c_pointer(output.arr), signal.arr, + pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), c_double_t(idx_step0), + pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), + method.value, c_float_t(off_grid))) + + return output
+ + +
[docs]def fft(signal, dim0 = None , scale = None): + """ + Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the fft. + + """ + + if dim0 is None: + dim0 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft(c_pointer(output.arr), signal.arr, c_double_t(scale), c_dim_t(dim0))) + return output
+ +
[docs]def fft2(signal, dim0 = None, dim1 = None , scale = None): + """ + Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the fft. + + """ + if dim0 is None: + dim0 = 0 + + if dim1 is None: + dim1 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft2(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1))) + return output
+ +
[docs]def fft3(signal, dim0 = None, dim1 = None , dim2 = None, scale = None): + """ + Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + dim2: optional: int. default: None. + - Specifies the size of the output. + - If None, dim2 is calculated to be the third dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the fft. + + """ + if dim0 is None: + dim0 = 0 + + if dim1 is None: + dim1 = 0 + + if dim2 is None: + dim2 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft3(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1), c_dim_t(dim2))) + return output
+ +
[docs]def ifft(signal, dim0 = None , scale = None): + """ + Inverse Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (dim0) + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the inverse fft. + + Note + ---- + + The output is always complex. + + """ + + if dim0 is None: + dim0 = signal.dims()[0] + + if scale is None: + scale = 1.0/float(dim0) + + output = Array() + safe_call(backend.get().af_ifft(c_pointer(output.arr), signal.arr, c_double_t(scale), c_dim_t(dim0))) + return output
+ +
[docs]def ifft2(signal, dim0 = None, dim1 = None , scale = None): + """ + Inverse Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (dim0 * dim1) + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the inverse fft. + + Note + ---- + + The output is always complex. + + """ + + dims = signal.dims() + + if dim0 is None: + dim0 = dims[0] + + if dim1 is None: + dim1 = dims[1] + + if scale is None: + scale = 1.0/float(dim0 * dim1) + + output = Array() + safe_call(backend.get().af_ifft2(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1))) + return output
+ +
[docs]def ifft3(signal, dim0 = None, dim1 = None , dim2 = None, scale = None): + """ + Inverse Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + dim2: optional: int. default: None. + - Specifies the size of the output. + - If None, dim2 is calculated to be the third dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (dim0 * dim1 * dim2). + + Returns + ------- + + output: af.Array + A complex af.Array containing the full output of the inverse fft. + + Note + ---- + + The output is always complex. + + """ + + dims = signal.dims() + + if dim0 is None: + dim0 = dims[0] + + if dim1 is None: + dim1 = dims[1] + + if dim2 is None: + dim2 = dims[2] + + if scale is None: + scale = 1.0 / float(dim0 * dim1 * dim2) + + output = Array() + safe_call(backend.get().af_ifft3(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1), c_dim_t(dim2))) + return output
+ +
[docs]def fft_inplace(signal, scale = None): + """ + In-place Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + """ + + if scale is None: + scale = 1.0 + + safe_call(backend.get().af_fft_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def fft2_inplace(signal, scale = None): + """ + In-place Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + """ + + if scale is None: + scale = 1.0 + + safe_call(backend.get().af_fft2_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def fft3_inplace(signal, scale = None): + """ + In-place Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + """ + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft3_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def ifft_inplace(signal, scale = None): + """ + Inverse In-place Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (signal.dims()[0]) + """ + + if scale is None: + dim0 = signal.dims()[0] + scale = 1.0/float(dim0) + + safe_call(backend.get().af_ifft_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def ifft2_inplace(signal, scale = None): + """ + Inverse In-place Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (signal.dims()[0] * signal.dims()[1]) + """ + + dims = signal.dims() + + if scale is None: + dim0 = dims[0] + dim1 = dims[1] + scale = 1.0/float(dim0 * dim1) + + safe_call(backend.get().af_ifft2_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def ifft3_inplace(signal, scale = None): + """ + Inverse In-place Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1.0 / (signal.dims()[0] * signal.dims()[1] * signal.dims()[2]). + """ + + dims = signal.dims() + + if scale is None: + dim0 = dims[0] + dim1 = dims[1] + dim2 = dims[2] + scale = 1.0 / float(dim0 * dim1 * dim2) + + safe_call(backend.get().af_ifft3_inplace(signal.arr, c_double_t(scale)))
+ +
[docs]def fft_r2c(signal, dim0 = None , scale = None): + """ + Real to Complex Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the non-redundant parts of the full FFT. + + """ + + if dim0 is None: + dim0 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft_r2c(c_pointer(output.arr), signal.arr, c_double_t(scale), c_dim_t(dim0))) + return output
+ +
[docs]def fft2_r2c(signal, dim0 = None, dim1 = None , scale = None): + """ + Real to Complex Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the non-redundant parts of the full FFT. + + """ + if dim0 is None: + dim0 = 0 + + if dim1 is None: + dim1 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft2_r2c(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1))) + return output
+ +
[docs]def fft3_r2c(signal, dim0 = None, dim1 = None , dim2 = None, scale = None): + """ + Real to Complex Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + dim0: optional: int. default: None. + - Specifies the size of the output. + - If None, dim0 is calculated to be the first dimension of `signal`. + + dim1: optional: int. default: None. + - Specifies the size of the output. + - If None, dim1 is calculated to be the second dimension of `signal`. + + dim2: optional: int. default: None. + - Specifies the size of the output. + - If None, dim2 is calculated to be the third dimension of `signal`. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1. + + Returns + ------- + + output: af.Array + A complex af.Array containing the non-redundant parts of the full FFT. + + """ + if dim0 is None: + dim0 = 0 + + if dim1 is None: + dim1 = 0 + + if dim2 is None: + dim2 = 0 + + if scale is None: + scale = 1.0 + + output = Array() + safe_call(backend.get().af_fft3_r2c(c_pointer(output.arr), signal.arr, c_double_t(scale), + c_dim_t(dim0), c_dim_t(dim1), c_dim_t(dim2))) + return output
+ +def _get_c2r_dim(dim, is_odd): + return 2 *(dim - 1) + int(is_odd) + +
[docs]def fft_c2r(signal, is_odd = False, scale = None): + """ + Real to Complex Fast Fourier Transform: 1D + + Parameters + ---------- + + signal: af.Array + A 1 dimensional signal or a batch of 1 dimensional signals. + + is_odd: optional: Boolean. default: False. + - Specifies if the first dimension of output should be even or odd. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1 / (signal.dims()[0]). + + Returns + ------- + + output: af.Array + A real af.Array containing the full output of the fft. + + """ + + + if scale is None: + dim0 = _get_c2r_dim(signal.dims()[0], is_odd) + scale = 1.0/float(dim0) + + output = Array() + safe_call(backend.get().af_fft_c2r(c_pointer(output.arr), signal.arr, c_double_t(scale), is_odd)) + return output
+ +
[docs]def fft2_c2r(signal, is_odd = False, scale = None): + """ + Real to Complex Fast Fourier Transform: 2D + + Parameters + ---------- + + signal: af.Array + A 2 dimensional signal or a batch of 2 dimensional signals. + + is_odd: optional: Boolean. default: False. + - Specifies if the first dimension of output should be even or odd. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1 / (signal.dims()[0] * signal.dims()[1]). + + Returns + ------- + + output: af.Array + A real af.Array containing the full output of the fft. + + """ + dims = signal.dims() + + if scale is None: + dim0 = _get_c2r_dim(dims[0], is_odd) + dim1 = dims[1] + scale = 1.0/float(dim0 * dim1) + + output = Array() + safe_call(backend.get().af_fft2_c2r(c_pointer(output.arr), signal.arr, c_double_t(scale), is_odd)) + return output
+ +
[docs]def fft3_c2r(signal, is_odd = False, scale = None): + """ + Real to Complex Fast Fourier Transform: 3D + + Parameters + ---------- + + signal: af.Array + A 3 dimensional signal or a batch of 3 dimensional signals. + + is_odd: optional: Boolean. default: False. + - Specifies if the first dimension of output should be even or odd. + + scale: optional: scalar. default: None. + - Specifies the scaling factor. + - If None, scale is set to 1 / (signal.dims()[0] * signal.dims()[1] * signal.dims()[2]). + + Returns + ------- + + output: af.Array + A real af.Array containing the full output of the fft. + + """ + dims = signal.dims() + + if scale is None: + dim0 = _get_c2r_dim(dims[0], is_odd) + dim1 = dims[1] + dim2 = dims[2] + scale = 1.0/float(dim0 * dim1 * dim2) + + output = Array() + safe_call(backend.get().af_fft3_c2r(c_pointer(output.arr), signal.arr, c_double_t(scale), is_odd)) + return output
+ + +
[docs]def dft(signal, odims=(None, None, None, None), scale = None): + + """ + Non batched Fourier transform. + + This function performs n-dimensional fourier transform depending on the input dimensions. + + Parameters + ---------- + + signal: af.Array + - A multi dimensional arrayfire array. + + odims: optional: tuple of ints. default: (None, None, None, None). + - If None, calculated to be `signal.dims()` + + scale: optional: scalar. default: None. + - Scale factor for the fourier transform. + - If none, calculated to be 1.0. + + Returns + ------- + output: af.Array + - A complex array that is the ouput of n-dimensional fourier transform. + + """ + + odims4 = dim4_to_tuple(odims, default=None) + + dims = signal.dims() + ndims = len(dims) + + if (ndims == 1): + return fft(signal, dims[0], scale) + elif (ndims == 2): + return fft2(signal, dims[0], dims[1], scale) + else: + return fft3(signal, dims[0], dims[1], dims[2], scale)
+ +
[docs]def idft(signal, scale = None, odims=(None, None, None, None)): + """ + Non batched Inverse Fourier transform. + + This function performs n-dimensional inverse fourier transform depending on the input dimensions. + + Parameters + ---------- + + signal: af.Array + - A multi dimensional arrayfire array. + + odims: optional: tuple of ints. default: (None, None, None, None). + - If None, calculated to be `signal.dims()` + + scale: optional: scalar. default: None. + - Scale factor for the fourier transform. + - If none, calculated to be 1.0 / signal.elements() + + Returns + ------- + output: af.Array + - A complex array that is the ouput of n-dimensional inverse fourier transform. + + Note + ---- + + the output is always complex. + + """ + + odims4 = dim4_to_tuple(odims, default=None) + + dims = signal.dims() + ndims = len(dims) + + if (ndims == 1): + return ifft(signal, scale, dims[0]) + elif (ndims == 2): + return ifft2(signal, scale, dims[0], dims[1]) + else: + return ifft3(signal, scale, dims[0], dims[1], dims[2])
+ +
[docs]def convolve1(signal, kernel, conv_mode = CONV_MODE.DEFAULT, conv_domain = CONV_DOMAIN.AUTO): + """ + Convolution: 1D + + Parameters + ----------- + + signal: af.Array + - A 1 dimensional signal or batch of 1 dimensional signals. + + kernel: af.Array + - A 1 dimensional kernel or batch of 1 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + conv_domain: optional: af.CONV_DOMAIN. default: af.CONV_DOMAIN.AUTO. + - Specifies the domain in which convolution is performed. + - af.CONV_DOMAIN.SPATIAL: Performs convolution in spatial domain. + - af.CONV_DOMAIN.FREQ: Performs convolution in frequency domain. + - af.CONV_DOMAIN.AUTO: Switches between spatial and frequency based on input size. + + Returns + -------- + + output: af.Array + - Output of 1D convolution. + + Note + ----- + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m 1 1 1] | [m 1 1 1] | [m 1 1 1] | + | [m n 1 1] | [m n 1 1] | [m n 1 1] | + | [m n p 1] | [m n 1 1] | [m n p 1] | + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n 1 q] | [m n p q] | + | [m n 1 p] | [m n q 1] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_convolve1(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value, conv_domain.value)) + return output
+ +
[docs]def convolve2(signal, kernel, conv_mode = CONV_MODE.DEFAULT, conv_domain = CONV_DOMAIN.AUTO): + """ + Convolution: 2D + + Parameters + ----------- + + signal: af.Array + - A 2 dimensional signal or batch of 2 dimensional signals. + + kernel: af.Array + - A 2 dimensional kernel or batch of 2 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + conv_domain: optional: af.CONV_DOMAIN. default: af.CONV_DOMAIN.AUTO. + - Specifies the domain in which convolution is performed. + - af.CONV_DOMAIN.SPATIAL: Performs convolution in spatial domain. + - af.CONV_DOMAIN.FREQ: Performs convolution in frequency domain. + - af.CONV_DOMAIN.AUTO: Switches between spatial and frequency based on input size. + + Returns + -------- + + output: af.Array + - Output of 2D convolution. + + Note + ----- + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m n 1 1] | [m n 1 1] | [m n 1 1] | + | [m n p 1] | [m n 1 1] | [m n p 1] | + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n 1 q] | [m n p q] | + | [m n 1 p] | [m n q 1] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_convolve2(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value, conv_domain.value)) + return output
+ +
[docs]def convolve2NN(signal, kernel, stride = (1, 1), padding = (0, 0), dilation = (1, 1)): + """ + 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. + + 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: af.Array + - A 2 dimensional signal or batch of 2 dimensional signals. + + kernel: af.Array + - A 2 dimensional kernel or batch of 2 dimensional kernels. + + stride: tuple of ints. default: (1, 1). + - Specifies how much to stride along each dimension + + padding: tuple of ints. default: (0, 0). + - Specifies signal padding along each dimension + + dilation: tuple of ints. default: (1, 1). + - Specifies how much to dilate kernel along each dimension before convolution + + Returns + -------- + + output: af.Array + - Convolved 2D array. + + """ + output = Array() + stride_dim = dim4(stride[0], stride[1]) + padding_dim = dim4(padding[0], padding[1]) + dilation_dim = dim4(dilation[0], dilation[1]) + + safe_call(backend.get().af_convolve2_nn(c_pointer(output.arr), signal.arr, kernel.arr, + 2, c_pointer(stride_dim), + 2, c_pointer(padding_dim), + 2, c_pointer(dilation_dim))) + return output
+ +
[docs]def convolve2_separable(col_kernel, row_kernel, signal, conv_mode = CONV_MODE.DEFAULT): + """ + Convolution: 2D separable convolution + + Parameters + ----------- + + col_kernel: af.Array + - A column vector to be applied along each column of `signal` + + row_kernel: af.Array + - A row vector to be applied along each row of `signal` + + signal: af.Array + - A 2 dimensional signal or batch of 2 dimensional signals. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + Returns + -------- + + output: af.Array + - Output of 2D sepearable convolution. + """ + output = Array() + safe_call(backend.get().af_convolve2_sep(c_pointer(output.arr), + col_kernel.arr, row_kernel.arr,signal.arr, + conv_mode.value)) + return output
+ +
[docs]def convolve3(signal, kernel, conv_mode = CONV_MODE.DEFAULT, conv_domain = CONV_DOMAIN.AUTO): + """ + Convolution: 3D + + Parameters + ----------- + + signal: af.Array + - A 3 dimensional signal or batch of 3 dimensional signals. + + kernel: af.Array + - A 3 dimensional kernel or batch of 3 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + conv_domain: optional: af.CONV_DOMAIN. default: af.CONV_DOMAIN.AUTO. + - Specifies the domain in which convolution is performed. + - af.CONV_DOMAIN.SPATIAL: Performs convolution in spatial domain. + - af.CONV_DOMAIN.FREQ: Performs convolution in frequency domain. + - af.CONV_DOMAIN.AUTO: Switches between spatial and frequency based on input size. + + Returns + -------- + + output: af.Array + - Output of 3D convolution. + + Note + ----- + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n p q] | [m n p q] | + | [m n q p] | [m n q p] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_convolve3(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value, conv_domain.value)) + return output
+ +
[docs]def convolve(signal, kernel, conv_mode = CONV_MODE.DEFAULT, conv_domain = CONV_DOMAIN.AUTO): + """ + Non batched Convolution. + + This function performs n-dimensional convolution based on input dimensionality. + + Parameters + ----------- + + signal: af.Array + - An n-dimensional array. + + kernel: af.Array + - A n-dimensional kernel. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + conv_domain: optional: af.CONV_DOMAIN. default: af.CONV_DOMAIN.AUTO. + - Specifies the domain in which convolution is performed. + - af.CONV_DOMAIN.SPATIAL: Performs convolution in spatial domain. + - af.CONV_DOMAIN.FREQ: Performs convolution in frequency domain. + - af.CONV_DOMAIN.AUTO: Switches between spatial and frequency based on input size. + + Returns + -------- + + output: af.Array + - Output of n-dimensional convolution. + """ + + dims = signal.dims() + ndims = len(dims) + + if (ndims == 1): + return convolve1(signal, kernel, conv_mode, conv_domain) + elif (ndims == 2): + return convolve2(signal, kernel, conv_mode, conv_domain) + else: + return convolve3(signal, kernel, conv_mode, conv_domain)
+ +
[docs]def fft_convolve1(signal, kernel, conv_mode = CONV_MODE.DEFAULT): + """ + FFT based Convolution: 1D + + Parameters + ----------- + + signal: af.Array + - A 1 dimensional signal or batch of 1 dimensional signals. + + kernel: af.Array + - A 1 dimensional kernel or batch of 1 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + Returns + -------- + + output: af.Array + - Output of 1D convolution. + + Note + ----- + + This is same as convolve1(..., conv_mode=af.CONV_MODE.FREQ) + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m 1 1 1] | [m 1 1 1] | [m 1 1 1] | + | [m n 1 1] | [m n 1 1] | [m n 1 1] | + | [m n p 1] | [m n 1 1] | [m n p 1] | + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n 1 q] | [m n p q] | + | [m n 1 p] | [m n q 1] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_fft_convolve1(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value)) + return output
+ +
[docs]def fft_convolve2(signal, kernel, conv_mode = CONV_MODE.DEFAULT): + """ + FFT based Convolution: 2D + + Parameters + ----------- + + signal: af.Array + - A 2 dimensional signal or batch of 2 dimensional signals. + + kernel: af.Array + - A 2 dimensional kernel or batch of 2 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + Returns + -------- + + output: af.Array + - Output of 2D convolution. + + Note + ----- + + This is same as convolve2(..., conv_mode=af.CONV_MODE.FREQ) + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m n 1 1] | [m n 1 1] | [m n 1 1] | + | [m n p 1] | [m n 1 1] | [m n p 1] | + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n 1 q] | [m n p q] | + | [m n 1 p] | [m n q 1] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_fft_convolve2(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value)) + return output
+ +
[docs]def fft_convolve3(signal, kernel, conv_mode = CONV_MODE.DEFAULT): + """ + FFT based Convolution: 3D + + Parameters + ----------- + + signal: af.Array + - A 3 dimensional signal or batch of 3 dimensional signals. + + kernel: af.Array + - A 3 dimensional kernel or batch of 3 dimensional kernels. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + Returns + -------- + + output: af.Array + - Output of 3D convolution. + + Note + ----- + + This is same as convolve3(..., conv_mode=af.CONV_MODE.FREQ) + + Supported batch combinations: + + | Signal | Kernel | output | + |:---------:|:---------:|:---------:| + | [m n p 1] | [m n p 1] | [m n p 1] | + | [m n p 1] | [m n p q] | [m n p q] | + | [m n q p] | [m n q p] | [m n q p] | + + """ + output = Array() + safe_call(backend.get().af_fft_convolve3(c_pointer(output.arr), signal.arr, kernel.arr, + conv_mode.value)) + return output
+ +
[docs]def fft_convolve(signal, kernel, conv_mode = CONV_MODE.DEFAULT): + """ + Non batched FFT Convolution. + + This function performs n-dimensional convolution based on input dimensionality. + + Parameters + ----------- + + signal: af.Array + - An n-dimensional array. + + kernel: af.Array + - A n-dimensional kernel. + + conv_mode: optional: af.CONV_MODE. default: af.CONV_MODE.DEFAULT. + - Specifies if the output does full convolution (af.CONV_MODE.EXPAND) or + maintains the same size as input (af.CONV_MODE.DEFAULT). + + Returns + -------- + + output: af.Array + - Output of n-dimensional convolution. + + Note + ----- + + This is same as convolve(..., conv_mode=af.CONV_MODE.FREQ) + + """ + dims = signal.dims() + ndims = len(dims) + + if (ndims == 1): + return fft_convolve1(signal, kernel, conv_mode) + elif (ndims == 2): + return fft_convolve2(signal, kernel, conv_mode) + else: + return fft_convolve3(signal, kernel, conv_mode)
+ +
[docs]def fir(B, X): + """ + Finite impulse response filter. + + Parameters + ---------- + + B : af.Array + A 1 dimensional array containing the coefficients of the filter. + + X : af.Array + A 1 dimensional array containing the signal. + + Returns + ------- + + Y : af.Array + The output of the filter. + + """ + Y = Array() + safe_call(backend.get().af_fir(c_pointer(Y.arr), B.arr, X.arr)) + return Y
+ +
[docs]def iir(B, A, X): + """ + Infinite impulse response filter. + + Parameters + ---------- + + B : af.Array + A 1 dimensional array containing the feed forward coefficients of the filter. + + A : af.Array + A 1 dimensional array containing the feed back coefficients of the filter. + + X : af.Array + A 1 dimensional array containing the signal. + + Returns + ------- + + Y : af.Array + The output of the filter. + + """ + Y = Array() + safe_call(backend.get().af_iir(c_pointer(Y.arr), B.arr, A.arr, X.arr)) + return Y
+ +
[docs]def medfilt(signal, w0 = 3, w1 = 3, edge_pad = PAD.ZERO): + """ + Apply median filter for the signal. + + Parameters + ---------- + signal : af.Array + - A 2 D arrayfire array representing a signal, or + - A multi dimensional array representing batch of signals. + + w0 : optional: int. default: 3. + - The length of the filter along the first dimension. + + w1 : optional: int. default: 3. + - The length of the filter along the second dimension. + + edge_pad : optional: af.PAD. default: af.PAD.ZERO + - Flag specifying how the median at the edge should be treated. + + Returns + --------- + + output : af.Array + - The signal after median filter is applied. + + """ + output = Array() + safe_call(backend.get().af_medfilt(c_pointer(output.arr), + signal.arr, c_dim_t(w0), + c_dim_t(w1), edge_pad.value)) + return output
+ +
[docs]def medfilt1(signal, length = 3, edge_pad = PAD.ZERO): + """ + Apply median filter for the signal. + + Parameters + ---------- + signal : af.Array + - A 1 D arrayfire array representing a signal, or + - A multi dimensional array representing batch of signals. + + length : optional: int. default: 3. + - The length of the filter. + + edge_pad : optional: af.PAD. default: af.PAD.ZERO + - Flag specifying how the median at the edge should be treated. + + Returns + --------- + + output : af.Array + - The signal after median filter is applied. + + """ + output = Array() + safe_call(backend.get().af_medfilt1(c_pointer(output.arr), signal.arr, c_dim_t(length), edge_pad.value)) + return output
+ +
[docs]def medfilt2(signal, w0 = 3, w1 = 3, edge_pad = PAD.ZERO): + """ + Apply median filter for the signal. + + Parameters + ---------- + signal : af.Array + - A 2 D arrayfire array representing a signal, or + - A multi dimensional array representing batch of signals. + + w0 : optional: int. default: 3. + - The length of the filter along the first dimension. + + w1 : optional: int. default: 3. + - The length of the filter along the second dimension. + + edge_pad : optional: af.PAD. default: af.PAD.ZERO + - Flag specifying how the median at the edge should be treated. + + Returns + --------- + + output : af.Array + - The signal after median filter is applied. + + """ + output = Array() + safe_call(backend.get().af_medfilt2(c_pointer(output.arr), + signal.arr, c_dim_t(w0), + c_dim_t(w1), edge_pad.value)) + return output
+ +
[docs]def set_fft_plan_cache_size(cache_size): + """ + Sets plan cache size. + + Parameters + ---------- + + cache_size : scalar + the number of plans that shall be cached + """ + safe_call(backend.get().af_set_fft_plan_cache_size(c_size_t(cache_size)))
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/sparse.html b/_modules/arrayfire/sparse.html new file mode 100644 index 000000000..89bef9c19 --- /dev/null +++ b/_modules/arrayfire/sparse.html @@ -0,0 +1,380 @@ + + + + + + + + arrayfire.sparse — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.sparse

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Functions to create and manipulate sparse matrices.
+"""
+
+from .library import *
+from .array import *
+import numbers
+from .interop import to_array
+
+__to_sparse_enum = [STORAGE.DENSE,
+                    STORAGE.CSR,
+                    STORAGE.CSC,
+                    STORAGE.COO]
+
+
+
[docs]def create_sparse(values, row_idx, col_idx, nrows, ncols, storage = STORAGE.CSR): + """ + Create a sparse matrix from it's constituent parts. + + Parameters + ---------- + + values : af.Array. + - Contains the non zero elements of the sparse array. + + row_idx : af.Array. + - Contains row indices of the sparse array. + + col_idx : af.Array. + - Contains column indices of the sparse array. + + nrows : int. + - specifies the number of rows in sparse matrix. + + ncols : int. + - specifies the number of columns in sparse matrix. + + storage : optional: arrayfire.STORAGE. default: arrayfire.STORAGE.CSR. + - Can be one of arrayfire.STORAGE.CSR, arrayfire.STORAGE.COO. + + Returns + ------- + + A sparse matrix. + """ + assert(isinstance(values, Array)) + assert(isinstance(row_idx, Array)) + assert(isinstance(col_idx, Array)) + out = Array() + safe_call(backend.get().af_create_sparse_array(c_pointer(out.arr), c_dim_t(nrows), c_dim_t(ncols), + values.arr, row_idx.arr, col_idx.arr, storage.value)) + return out
+ +
[docs]def create_sparse_from_host(values, row_idx, col_idx, nrows, ncols, storage = STORAGE.CSR): + """ + Create a sparse matrix from it's constituent parts. + + Parameters + ---------- + + values : Any datatype that can be converted to array. + - Contains the non zero elements of the sparse array. + + row_idx : Any datatype that can be converted to array. + - Contains row indices of the sparse array. + + col_idx : Any datatype that can be converted to array. + - Contains column indices of the sparse array. + + nrows : int. + - specifies the number of rows in sparse matrix. + + ncols : int. + - specifies the number of columns in sparse matrix. + + storage : optional: arrayfire.STORAGE. default: arrayfire.STORAGE.CSR. + - Can be one of arrayfire.STORAGE.CSR, arrayfire.STORAGE.COO. + + Returns + ------- + + A sparse matrix. + """ + return create_sparse(to_array(values), + to_array(row_idx).as_type(Dtype.s32), + to_array(col_idx).as_type(Dtype.s32), + nrows, ncols, storage)
+ +
[docs]def create_sparse_from_dense(dense, storage = STORAGE.CSR): + """ + Create a sparse matrix from a dense matrix. + + Parameters + ---------- + + dense : af.Array. + - A dense matrix. + + storage : optional: arrayfire.STORAGE. default: arrayfire.STORAGE.CSR. + - Can be one of arrayfire.STORAGE.CSR, arrayfire.STORAGE.COO. + + Returns + ------- + + A sparse matrix. + """ + assert(isinstance(dense, Array)) + out = Array() + safe_call(backend.get().af_create_sparse_array_from_dense(c_pointer(out.arr), dense.arr, storage.value)) + return out
+ +
[docs]def convert_sparse_to_dense(sparse): + """ + Create a dense matrix from a sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + ------- + + A dense matrix. + """ + out = Array() + safe_call(backend.get().af_sparse_to_dense(c_pointer(out.arr), sparse.arr)) + return out
+ +
[docs]def sparse_get_info(sparse): + """ + Get the constituent arrays and storage info from a sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + (values, row_idx, col_idx, storage) where + values : arrayfire.Array containing non zero elements from sparse matrix + row_idx : arrayfire.Array containing the row indices + col_idx : arrayfire.Array containing the column indices + storage : sparse storage + """ + values = Array() + row_idx = Array() + col_idx = Array() + stype = c_int_t(0) + safe_call(backend.get().af_sparse_get_info(c_pointer(values.arr), c_pointer(row_idx.arr), + c_pointer(col_idx.arr), c_pointer(stype), + sparse.arr)) + return (values, row_idx, col_idx, __to_sparse_enum[stype.value])
+ +
[docs]def sparse_get_values(sparse): + """ + Get the non zero values from sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + arrayfire array containing the non zero elements. + + """ + values = Array() + safe_call(backend.get().af_sparse_get_values(c_pointer(values.arr), sparse.arr)) + return values
+ +
[docs]def sparse_get_row_idx(sparse): + """ + Get the row indices from sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + arrayfire array containing the non zero elements. + + """ + row_idx = Array() + safe_call(backend.get().af_sparse_get_row_idx(c_pointer(row_idx.arr), sparse.arr)) + return row_idx
+ +
[docs]def sparse_get_col_idx(sparse): + """ + Get the column indices from sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + arrayfire array containing the non zero elements. + + """ + col_idx = Array() + safe_call(backend.get().af_sparse_get_col_idx(c_pointer(col_idx.arr), sparse.arr)) + return col_idx
+ +
[docs]def sparse_get_nnz(sparse): + """ + Get the column indices from sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + Number of non zero elements in the sparse matrix. + + """ + nnz = c_dim_t(0) + safe_call(backend.get().af_sparse_get_nnz(c_pointer(nnz), sparse.arr)) + return nnz.value
+ +
[docs]def sparse_get_storage(sparse): + """ + Get the column indices from sparse matrix. + + Parameters + ---------- + + sparse : af.Array. + - A sparse matrix. + + Returns + -------- + Number of non zero elements in the sparse matrix. + + """ + storage = c_int_t(0) + safe_call(backend.get().af_sparse_get_storage(c_pointer(storage), sparse.arr)) + return __to_sparse_enum[storage.value]
+ +
[docs]def convert_sparse(sparse, storage): + """ + Convert sparse matrix from one format to another. + + Parameters + ---------- + + storage : arrayfire.STORAGE. + + Returns + ------- + + Sparse matrix converted to the appropriate type. + """ + out = Array() + safe_call(backend.get().af_sparse_convert_to(c_pointer(out.arr), sparse.arr, storage.value)) + return out
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/statistics.html b/_modules/arrayfire/statistics.html new file mode 100644 index 000000000..a87e08272 --- /dev/null +++ b/_modules/arrayfire/statistics.html @@ -0,0 +1,408 @@ + + + + + + + + arrayfire.statistics — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.statistics

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Statistical algorithms (mean, var, stdev, etc).
+"""
+
+from .library import *
+from .array import *
+
+
[docs]def mean(a, weights=None, dim=None): + """ + Calculate mean along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + weights: optional: af.Array. default: None. + Array to calculate the weighted mean. Must match size of the + input array. + + dim: optional: int. default: None. + The dimension for which to obtain the mean from input data. + + Returns + ------- + output: af.Array + Array containing the mean of the input array along a given + dimension. + """ + if dim is not None: + out = Array() + + if weights is None: + safe_call(backend.get().af_mean(c_pointer(out.arr), a.arr, c_int_t(dim))) + else: + safe_call(backend.get().af_mean_weighted(c_pointer(out.arr), a.arr, weights.arr, c_int_t(dim))) + + return out + else: + real = c_double_t(0) + imag = c_double_t(0) + + if weights is None: + safe_call(backend.get().af_mean_all(c_pointer(real), c_pointer(imag), a.arr)) + else: + safe_call(backend.get().af_mean_all_weighted(c_pointer(real), c_pointer(imag), a.arr, weights.arr)) + + real = real.value + imag = imag.value + + return real if imag == 0 else real + imag * 1j
+ +
[docs]def var(a, isbiased=False, weights=None, dim=None): + """ + Calculate variance along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + isbiased: optional: Boolean. default: False. + Boolean denoting population variance (false) or sample + variance (true). + + weights: optional: af.Array. default: None. + Array to calculate for the weighted mean. Must match size of + the input array. + + dim: optional: int. default: None. + The dimension for which to obtain the variance from input data. + + Returns + ------- + output: af.Array + Array containing the variance of the input array along a given + dimension. + """ + if dim is not None: + out = Array() + + if weights is None: + safe_call(backend.get().af_var(c_pointer(out.arr), a.arr, isbiased, c_int_t(dim))) + else: + safe_call(backend.get().af_var_weighted(c_pointer(out.arr), a.arr, weights.arr, c_int_t(dim))) + + return out + else: + real = c_double_t(0) + imag = c_double_t(0) + + if weights is None: + safe_call(backend.get().af_var_all(c_pointer(real), c_pointer(imag), a.arr, isbiased)) + else: + safe_call(backend.get().af_var_all_weighted(c_pointer(real), c_pointer(imag), a.arr, weights.arr)) + + real = real.value + imag = imag.value + + return real if imag == 0 else real + imag * 1j
+ +
[docs]def meanvar(a, weights=None, bias=VARIANCE.DEFAULT, dim=-1): + """ + Calculate mean and variance along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + weights: optional: af.Array. default: None. + Array to calculate for the weighted mean. Must match size of + the input array. + + bias: optional: af.VARIANCE. default: DEFAULT. + population variance(VARIANCE.POPULATION) or + sample variance(VARIANCE.SAMPLE). + + dim: optional: int. default: -1. + The dimension for which to obtain the variance from input data. + + Returns + ------- + mean: af.Array + Array containing the mean of the input array along a given + dimension. + variance: af.Array + Array containing the variance of the input array along a given + dimension. + """ + + mean_out = Array() + var_out = Array() + + if weights is None: + weights = Array() + + safe_call(backend.get().af_meanvar(c_pointer(mean_out.arr), c_pointer(var_out.arr), + a.arr, weights.arr, bias.value, c_int_t(dim))) + + return mean_out, var_out
+ + +
[docs]def stdev(a, dim=None): + """ + Calculate standard deviation along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + dim: optional: int. default: None. + The dimension for which to obtain the standard deviation from + input data. + + Returns + ------- + output: af.Array + Array containing the standard deviation of the input array + along a given dimension. + """ + if dim is not None: + out = Array() + safe_call(backend.get().af_stdev(c_pointer(out.arr), a.arr, c_int_t(dim))) + return out + else: + real = c_double_t(0) + imag = c_double_t(0) + safe_call(backend.get().af_stdev_all(c_pointer(real), c_pointer(imag), a.arr)) + real = real.value + imag = imag.value + return real if imag == 0 else real + imag * 1j
+ +
[docs]def cov(a, isbiased=False, dim=None): + """ + Calculate covariance along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + isbiased: optional: Boolean. default: False. + Boolean denoting whether biased estimate should be taken. + + dim: optional: int. default: None. + The dimension for which to obtain the covariance from input data. + + Returns + ------- + output: af.Array + Array containing the covariance of the input array along a + given dimension. + """ + if dim is not None: + out = Array() + safe_call(backend.get().af_cov(c_pointer(out.arr), a.arr, isbiased, c_int_t(dim))) + return out + else: + real = c_double_t(0) + imag = c_double_t(0) + safe_call(backend.get().af_cov_all(c_pointer(real), c_pointer(imag), a.arr, isbiased)) + real = real.value + imag = imag.value + return real if imag == 0 else real + imag * 1j
+ +
[docs]def median(a, dim=None): + """ + Calculate median along a given dimension. + + Parameters + ---------- + a: af.Array + The input array. + + dim: optional: int. default: None. + The dimension for which to obtain the median from input data. + + Returns + ------- + output: af.Array + Array containing the median of the input array along a + given dimension. + """ + if dim is not None: + out = Array() + safe_call(backend.get().af_median(c_pointer(out.arr), a.arr, c_int_t(dim))) + return out + else: + real = c_double_t(0) + imag = c_double_t(0) + safe_call(backend.get().af_median_all(c_pointer(real), c_pointer(imag), a.arr)) + real = real.value + imag = imag.value + return real if imag == 0 else real + imag * 1j
+ +
[docs]def corrcoef(x, y): + """ + Calculate the correlation coefficient of the input arrays. + + Parameters + ---------- + x: af.Array + The first input array. + + y: af.Array + The second input array. + + Returns + ------- + output: af.Array + Array containing the correlation coefficient of the input arrays. + """ + real = c_double_t(0) + imag = c_double_t(0) + safe_call(backend.get().af_corrcoef(c_pointer(real), c_pointer(imag), x.arr, y.arr)) + real = real.value + imag = imag.value + return real if imag == 0 else real + imag * 1j
+ +
[docs]def topk(data, k, dim=0, order=TOPK.DEFAULT): + """ + Return top k elements along a single dimension. + + Parameters + ---------- + + data: af.Array + Input array to return k elements from. + + k: scalar. default: 0 + The number of elements to return from input array. + + dim: optional: scalar. default: 0 + The dimension along which the top k elements are + extracted. Note: at the moment, topk() only supports the + extraction of values along the first dimension. + + order: optional: af.TOPK. default: af.TOPK.DEFAULT + The ordering of k extracted elements. Defaults to top k max values. + + Returns + ------- + + values: af.Array + Top k elements from input array. + indices: af.Array + Corresponding index array to top k elements. + """ + + values = Array() + indices = Array() + + safe_call(backend.get().af_topk(c_pointer(values.arr), c_pointer(indices.arr), data.arr, k, c_int_t(dim), order.value)) + + return values,indices
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/timer.html b/_modules/arrayfire/timer.html new file mode 100644 index 000000000..01747590a --- /dev/null +++ b/_modules/arrayfire/timer.html @@ -0,0 +1,159 @@ + + + + + + + + arrayfire.timer — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.timer

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+"""
+Functions to time arrayfire.
+"""
+
+from .library import *
+from .device import (sync, eval)
+from time import time
+import math
+
+
[docs]def timeit(af_func, *args): + """ + Function to time arrayfire functions. + + Parameters + ---------- + + af_func : arrayfire function + + *args : arguments to `af_func` + + Returns + -------- + + t : Time in seconds + """ + + sample_trials = 3 + + sample_time = 1E20 + + for i in range(sample_trials): + start = time() + res = af_func(*args) + eval(res) + sync() + sample_time = min(sample_time, time() - start) + + if (sample_time >= 0.5): + return sample_time + + num_iters = max(math.ceil(1.0 / sample_time), 3.0) + + start = time() + for i in range(int(num_iters)): + res = af_func(*args) + eval(res) + sync() + sample_time = (time() - start) / num_iters + return sample_time
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/util.html b/_modules/arrayfire/util.html new file mode 100644 index 000000000..e51f6df7c --- /dev/null +++ b/_modules/arrayfire/util.html @@ -0,0 +1,253 @@ + + + + + + + + arrayfire.util — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.util

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Utility functions to help with Array metadata.
+"""
+
+from .library import *
+import numbers
+
+
[docs]def dim4(d0=1, d1=1, d2=1, d3=1): + c_dim4 = c_dim_t * 4 + out = c_dim4(1, 1, 1, 1) + + for i, dim in enumerate((d0, d1, d2, d3)): + if (dim is not None): out[i] = c_dim_t(dim) + + return out
+ +def _is_number(a): + return isinstance(a, numbers.Number) + +
[docs]def number_dtype(a): + if isinstance(a, bool): + return Dtype.b8 + if isinstance(a, int): + return Dtype.s64 + elif isinstance(a, float): + return Dtype.f64 + elif isinstance(a, complex): + return Dtype.c64 + else: + return to_dtype[a.dtype.char]
+ +
[docs]def implicit_dtype(number, a_dtype): + n_dtype = number_dtype(number) + n_value = n_dtype.value + + f64v = Dtype.f64.value + f32v = Dtype.f32.value + c32v = Dtype.c32.value + c64v = Dtype.c64.value + + if n_value == f64v and (a_dtype == f32v or a_dtype == c32v): + return Dtype.f32 + + if n_value == c64v and (a_dtype == f32v or a_dtype == c32v): + return Dtype.c32 + + return n_dtype
+ +
[docs]def dim4_to_tuple(dims, default=1): + assert(isinstance(dims, tuple)) + + if (default is not None): + assert(_is_number(default)) + + out = [default]*4 + + for i, dim in enumerate(dims): + out[i] = dim + + return tuple(out)
+ +
[docs]def to_str(c_str): + return str(c_str.value.decode('utf-8'))
+ +
[docs]def safe_call(af_error): + if (af_error != ERR.NONE.value): + err_str = c_char_ptr_t(0) + err_len = c_dim_t(0) + backend.get().af_get_last_error(c_pointer(err_str), c_pointer(err_len)) + raise RuntimeError(to_str(err_str))
+ +
[docs]def get_version(): + """ + Function to get the version of arrayfire. + """ + major=c_int_t(0) + minor=c_int_t(0) + patch=c_int_t(0) + safe_call(backend.get().af_get_version(c_pointer(major), c_pointer(minor), c_pointer(patch))) + return major.value,minor.value,patch.value
+ +
[docs]def get_reversion(): + """ + Function to get the revision hash of the library. + """ + return to_str(backend.get().af_get_revision())
+ +to_dtype = {'f' : Dtype.f32, + 'd' : Dtype.f64, + 'b' : Dtype.b8, + 'B' : Dtype.u8, + 'h' : Dtype.s16, + 'H' : Dtype.u16, + 'i' : Dtype.s32, + 'I' : Dtype.u32, + 'l' : Dtype.s64, + 'L' : Dtype.u64, + 'F' : Dtype.c32, + 'D' : Dtype.c64, + 'hf': Dtype.f16} + +to_typecode = {Dtype.f32.value : 'f', + Dtype.f64.value : 'd', + Dtype.b8.value : 'b', + Dtype.u8.value : 'B', + Dtype.s16.value : 'h', + Dtype.u16.value : 'H', + Dtype.s32.value : 'i', + Dtype.u32.value : 'I', + Dtype.s64.value : 'l', + Dtype.u64.value : 'L', + Dtype.c32.value : 'F', + Dtype.c64.value : 'D', + Dtype.f16.value : 'hf'} + +to_c_type = {Dtype.f32.value : c_float_t, + Dtype.f64.value : c_double_t, + Dtype.b8.value : c_char_t, + Dtype.u8.value : c_uchar_t, + Dtype.s16.value : c_short_t, + Dtype.u16.value : c_ushort_t, + Dtype.s32.value : c_int_t, + Dtype.u32.value : c_uint_t, + Dtype.s64.value : c_longlong_t, + Dtype.u64.value : c_ulonglong_t, + Dtype.c32.value : c_float_t * 2, + Dtype.c64.value : c_double_t * 2, + Dtype.f16.value : c_ushort_t} + +to_typename = {Dtype.f32.value : 'float', + Dtype.f64.value : 'double', + Dtype.b8.value : 'bool', + Dtype.u8.value : 'unsigned char', + Dtype.s16.value : 'short int', + Dtype.u16.value : 'unsigned short int', + Dtype.s32.value : 'int', + Dtype.u32.value : 'unsigned int', + Dtype.s64.value : 'long int', + Dtype.u64.value : 'unsigned long int', + Dtype.c32.value : 'float complex', + Dtype.c64.value : 'double complex', + Dtype.f16.value : 'half'} +
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/arrayfire/vision.html b/_modules/arrayfire/vision.html new file mode 100644 index 000000000..fe1073c36 --- /dev/null +++ b/_modules/arrayfire/vision.html @@ -0,0 +1,544 @@ + + + + + + + + arrayfire.vision — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+ +

Source code for arrayfire.vision

+#######################################################
+# Copyright (c) 2015, ArrayFire
+# All rights reserved.
+#
+# This file is distributed under 3-clause BSD license.
+# The complete license agreement can be obtained at:
+# http://arrayfire.com/licenses/BSD-3-Clause
+########################################################
+
+"""
+Computer vision functions (FAST, ORB, etc)
+"""
+
+from .library import *
+from .array import *
+from .features import *
+
+
[docs]def fast(image, threshold=20.0, arc_length=9, non_max=True, feature_ratio=0.05, edge=3): + """ + FAST feature detector. + + Parameters + ---------- + + image : af.Array + A 2D array representing an image. + + threshold : scalar. optional. default: 20.0. + FAST threshold for which a pixel of the circle around a central pixel is consdered. + + arc_length : scalar. optional. default: 9 + The minimum length of arc length to be considered. Max length should be 16. + + non_max : Boolean. optional. default: True + A boolean flag specifying if non max suppression has to be performed. + + feature_ratio : scalar. optional. default: 0.05 (5%) + Specifies the maximum ratio of features to pixels in the image. + + edge : scalar. optional. default: 3. + Specifies the number of edge rows and columns to be ignored. + + Returns + --------- + features : af.Features() + Contains the location and score. Orientation and size are not computed. + + """ + out = Features() + safe_call(backend.get().af_fast(c_pointer(out.feat), + image.arr, c_float_t(threshold), c_uint_t(arc_length), non_max, + c_float_t(feature_ratio), c_uint_t(edge))) + return out
+ +
[docs]def harris(image, max_corners=500, min_response=1E5, sigma=1.0, block_size=0, k_thr=0.04): + """ + Harris corner detector. + + Parameters + ---------- + image : af.Array + A 2D array specifying an image. + + max_corners : scalar. optional. default: 500. + Specifies the maximum number of corners to be calculated. + + min_response : scalar. optional. default: 1E5 + Specifies the cutoff score for a corner to be considered + + sigma : scalar. optional. default: 1.0 + - Specifies the standard deviation of a circular window. + - Only used when block_size == 0. Must be >= 0.5 and <= 5.0. + + block_size : scalar. optional. default: 0 + Specifies the window size. + + k_thr : scalar. optional. default: 0.04 + Harris constant. must be >= 0.01 + + Returns + --------- + + features : af.Features() + Contains the location and score. Orientation and size are not computed. + + Note + ------ + + The covariation matrix will be square when `block_size` is used and circular when `sigma` is used. + + + """ + out = Features() + safe_call(backend.get().af_harris(c_pointer(out.feat), + image.arr, c_uint_t(max_corners), c_float_t(min_response), + c_float_t(sigma), c_uint_t(block_size), c_float_t(k_thr))) + return out
+ +
[docs]def orb(image, threshold=20.0, max_features=400, scale = 1.5, num_levels = 4, blur_image = False): + """ + ORB Feature descriptor. + + Parameters + ---------- + + image : af.Array + A 2D array representing an image. + + threshold : scalar. optional. default: 20.0. + FAST threshold for which a pixel of the circle around a central pixel is consdered. + + max_features : scalar. optional. default: 400. + Specifies the maximum number of features to be considered. + + scale : scalar. optional. default: 1.5. + Specifies the factor by which images are down scaled at each level. + + num_levles : scalar. optional. default: 4. + Specifies the number of levels used in the image pyramid. + + blur_image : Boolean. optional. default: False. + Flag specifying if the input has to be blurred before computing descriptors. + A gaussian filter with sigma = 2 is applied if True. + + + Returns + --------- + (features, descriptor) : tuple of (af.Features(), af.Array) + - descriptor is an af.Array of size N x 8 + + """ + feat = Features() + desc = Array() + safe_call(backend.get().af_orb(c_pointer(feat.feat), c_pointer(desc.arr), image.arr, + c_float_t(threshold), c_uint_t(max_features), + c_float_t(scale), c_uint_t(num_levels), blur_image)) + return feat, desc
+ +
[docs]def hamming_matcher(query, database, dim = 0, num_nearest = 1): + """ + Hamming distance matcher. + + Parameters + ----------- + + query : af.Array + A query feature descriptor + + database : af.Array + A multi dimensional array containing the feature descriptor database. + + dim : scalar. optional. default: 0. + Specifies the dimension along which feature descriptor lies. + + num_nearest: scalar. optional. default: 1. + Specifies the number of nearest neighbors to find. + + Returns + --------- + + (location, distance): tuple of af.Array + location and distances of closest matches. + + """ + index = Array() + dist = Array() + safe_call(backend.get().af_hamming_matcher(c_pointer(index.arr), c_pointer(dist.arr), + query.arr, database.arr, + c_dim_t(dim), c_dim_t(num_nearest))) + return index, dist
+ +
[docs]def nearest_neighbour(query, database, dim = 0, num_nearest = 1, match_type=MATCH.SSD): + """ + Nearest Neighbour matcher. + + Parameters + ----------- + + query : af.Array + A query feature descriptor + + database : af.Array + A multi dimensional array containing the feature descriptor database. + + dim : scalar. optional. default: 0. + Specifies the dimension along which feature descriptor lies. + + num_nearest: scalar. optional. default: 1. + Specifies the number of nearest neighbors to find. + + match_type: optional: af.MATCH. default: af.MATCH.SSD + Specifies the match function metric. + + Returns + --------- + + (location, distance): tuple of af.Array + location and distances of closest matches. + + """ + index = Array() + dist = Array() + safe_call(backend.get().af_nearest_neighbour(c_pointer(index.arr), c_pointer(dist.arr), + query.arr, database.arr, + c_dim_t(dim), c_dim_t(num_nearest), + match_type.value)) + return index, dist
+ +
[docs]def match_template(image, template, match_type = MATCH.SAD): + """ + Find the closest match of a template in an image. + + Parameters + ---------- + + image : af.Array + A multi dimensional array specifying an image or batch of images. + + template : af.Array + A multi dimensional array specifying a template or batch of templates. + + match_type: optional: af.MATCH. default: af.MATCH.SAD + Specifies the match function metric. + + Returns + -------- + out : af.Array + An array containing the score of the match at each pixel. + + """ + out = Array() + safe_call(backend.get().af_match_template(c_pointer(out.arr), + image.arr, template.arr, + match_type.value)) + return out
+ +
[docs]def susan(image, radius=3, diff_thr=32, geom_thr=10, feature_ratio=0.05, edge=3): + """ + SUSAN corner detector. + + Parameters + ---------- + image : af.Array + A 2D array specifying an image. + + radius : scalar. optional. default: 500. + Specifies the radius of each pixel neighborhood. + + diff_thr : scalar. optional. default: 1E5 + Specifies the intensity difference threshold. + + geom_thr : scalar. optional. default: 1.0 + Specifies the geometric threshold. + + feature_ratio : scalar. optional. default: 0.05 (5%) + Specifies the ratio of corners found to number of pixels. + + edge : scalar. optional. default: 3 + Specifies the number of edge rows and columns that are ignored. + + Returns + --------- + + features : af.Features() + Contains the location and score. Orientation and size are not computed. + + """ + out = Features() + safe_call(backend.get().af_susan(c_pointer(out.feat), + image.arr, c_uint_t(radius), c_float_t(diff_thr), + c_float_t(geom_thr), c_float_t(feature_ratio), + c_uint_t(edge))) + return out
+ +
[docs]def dog(image, radius1, radius2): + """ + Difference of gaussians. + + Parameters + ---------- + image : af.Array + A 2D array specifying an image. + + radius1 : scalar. + The radius of first gaussian kernel. + + radius2 : scalar. + The radius of second gaussian kernel. + + + Returns + -------- + + out : af.Array + A multi dimensional array containing the difference of gaussians. + + Note + ------ + + The sigma values are calculated to be 0.25 * radius. + """ + + out = Array() + safe_call(backend.get().af_dog(c_pointer(out.arr), + image.arr, radius1, radius2)) + return out
+ +
[docs]def sift(image, num_layers=3, contrast_threshold=0.04, edge_threshold=10.0, initial_sigma = 1.6, + double_input = True, intensity_scale = 0.00390625, feature_ratio = 0.05): + """ + SIFT feature detector and descriptor. + + Parameters + ---------- + image : af.Array + A 2D array representing an image + + num_layers : optional: integer. Default: 3 + Number of layers per octave. The number of octaves is calculated internally. + + contrast_threshold : optional: float. Default: 0.04 + Threshold used to filter out features that have low contrast. + + edge_threshold : optional: float. Default: 10.0 + Threshold used to filter out features that are too edge-like. + + initial_sigma : optional: float. Default: 1.6 + The sigma value used to filter the input image at the first octave. + + double_input : optional: bool. Default: True + If True, the input image will be scaled to double the size for the first octave. + + intensity_scale : optional: float. Default: 1.0/255 + The inverse of the difference between maximum and minimum intensity values. + + feature_ratio : optional: float. Default: 0.05 + Specifies the maximum number of features to detect as a ratio of image pixels. + + Returns + -------- + (features, descriptor) : tuple of (af.Features(), af.Array) + - descriptor is an af.Array of size N x 128 + + """ + + feat = Features() + desc = Array() + safe_call(backend.get().af_sift(c_pointer(feat.feat), c_pointer(desc.arr), + image.arr, num_layers, c_float_t(contrast_threshold), c_float_t(edge_threshold), + c_float_t(initial_sigma), double_input, c_float_t(intensity_scale), c_float_t(feature_ratio))) + + return (feat, desc)
+ +
[docs]def gloh(image, num_layers=3, contrast_threshold=0.04, edge_threshold=10.0, initial_sigma = 1.6, + double_input = True, intensity_scale = 0.00390625, feature_ratio = 0.05): + """ + GLOH feature detector and descriptor. + + Parameters + ---------- + image : af.Array + A 2D array representing an image + + num_layers : optional: integer. Default: 3 + Number of layers per octave. The number of octaves is calculated internally. + + contrast_threshold : optional: float. Default: 0.04 + Threshold used to filter out features that have low contrast. + + edge_threshold : optional: float. Default: 10.0 + Threshold used to filter out features that are too edge-like. + + initial_sigma : optional: float. Default: 1.6 + The sigma value used to filter the input image at the first octave. + + double_input : optional: bool. Default: True + If True, the input image will be scaled to double the size for the first octave. + + intensity_scale : optional: float. Default: 1.0/255 + The inverse of the difference between maximum and minimum intensity values. + + feature_ratio : optional: float. Default: 0.05 + Specifies the maximum number of features to detect as a ratio of image pixels. + + Returns + -------- + (features, descriptor) : tuple of (af.Features(), af.Array) + - descriptor is an af.Array of size N x 272 + + """ + + feat = Features() + desc = Array() + safe_call(backend.get().af_gloh(c_pointer(feat.feat), c_pointer(desc.arr), + image.arr, num_layers, c_float_t(contrast_threshold), + c_float_t(edge_threshold), c_float_t(initial_sigma), + double_input, c_float_t(intensity_scale), + c_float_t(feature_ratio))) + + return (feat, desc)
+ +
[docs]def homography(x_src, y_src, x_dst, y_dst, htype = HOMOGRAPHY.RANSAC, + ransac_threshold = 3.0, iters = 1000, out_type = Dtype.f32): + """ + Homography estimation + + Parameters + ---------- + x_src : af.Array + A list of x co-ordinates of the source points. + + y_src : af.Array + A list of y co-ordinates of the source points. + + x_dst : af.Array + A list of x co-ordinates of the destination points. + + y_dst : af.Array + A list of y co-ordinates of the destination points. + + htype : optional: af.HOMOGRAPHY. Default: HOMOGRAPHY.RANSAC + htype can be one of + - HOMOGRAPHY.RANSAC: RANdom SAmple Consensus will be used to evaluate quality. + - HOMOGRAPHY.LMEDS : Least MEDian of Squares is used to evaluate quality. + + ransac_threshold : optional: scalar. Default: 3.0 + If `htype` is HOMOGRAPHY.RANSAC, it specifies the L2-distance threshold for inliers. + + out_type : optional. af.Dtype. Default: Dtype.f32. + Specifies the output data type. + + Returns + ------- + (H, inliers) : A tuple of (af.Array, integer) + """ + + H = Array() + inliers = c_int_t(0) + safe_call(backend.get().af_homography(c_pointer(H), c_pointer(inliers), + x_src.arr, y_src.arr, x_dst.arr, y_dst.arr, + htype.value, ransac_threshold, iters, out_type.value)) + return (H, inliers)
+
+ +
+ +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 000000000..05358e9d8 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,124 @@ + + + + + + + + Overview: module code — ArrayFire Python documentation + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/arrayfire.algorithm.rst b/_sources/arrayfire.algorithm.rst.txt similarity index 100% rename from docs/arrayfire.algorithm.rst rename to _sources/arrayfire.algorithm.rst.txt diff --git a/_sources/arrayfire.algorithm.txt b/_sources/arrayfire.algorithm.txt new file mode 100644 index 000000000..e41092935 --- /dev/null +++ b/_sources/arrayfire.algorithm.txt @@ -0,0 +1,7 @@ +arrayfire.algorithm module +========================== + +.. automodule:: arrayfire.algorithm + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.arith.rst b/_sources/arrayfire.arith.rst.txt similarity index 100% rename from docs/arrayfire.arith.rst rename to _sources/arrayfire.arith.rst.txt diff --git a/_sources/arrayfire.arith.txt b/_sources/arrayfire.arith.txt new file mode 100644 index 000000000..d874a2ecd --- /dev/null +++ b/_sources/arrayfire.arith.txt @@ -0,0 +1,7 @@ +arrayfire.arith module +====================== + +.. automodule:: arrayfire.arith + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.array.rst b/_sources/arrayfire.array.rst.txt similarity index 100% rename from docs/arrayfire.array.rst rename to _sources/arrayfire.array.rst.txt diff --git a/_sources/arrayfire.array.txt b/_sources/arrayfire.array.txt new file mode 100644 index 000000000..84e335108 --- /dev/null +++ b/_sources/arrayfire.array.txt @@ -0,0 +1,7 @@ +arrayfire.array module +====================== + +.. automodule:: arrayfire.array + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.base.rst b/_sources/arrayfire.base.rst.txt similarity index 100% rename from docs/arrayfire.base.rst rename to _sources/arrayfire.base.rst.txt diff --git a/_sources/arrayfire.base.txt b/_sources/arrayfire.base.txt new file mode 100644 index 000000000..be1e420aa --- /dev/null +++ b/_sources/arrayfire.base.txt @@ -0,0 +1,7 @@ +arrayfire.base module +===================== + +.. automodule:: arrayfire.base + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.bcast.rst b/_sources/arrayfire.bcast.rst.txt similarity index 100% rename from docs/arrayfire.bcast.rst rename to _sources/arrayfire.bcast.rst.txt diff --git a/_sources/arrayfire.bcast.txt b/_sources/arrayfire.bcast.txt new file mode 100644 index 000000000..0bcd4e521 --- /dev/null +++ b/_sources/arrayfire.bcast.txt @@ -0,0 +1,7 @@ +arrayfire.bcast module +====================== + +.. automodule:: arrayfire.bcast + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.blas.rst b/_sources/arrayfire.blas.rst.txt similarity index 100% rename from docs/arrayfire.blas.rst rename to _sources/arrayfire.blas.rst.txt diff --git a/_sources/arrayfire.blas.txt b/_sources/arrayfire.blas.txt new file mode 100644 index 000000000..054f98fc5 --- /dev/null +++ b/_sources/arrayfire.blas.txt @@ -0,0 +1,7 @@ +arrayfire.blas module +===================== + +.. automodule:: arrayfire.blas + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.cuda.rst b/_sources/arrayfire.cuda.rst.txt similarity index 100% rename from docs/arrayfire.cuda.rst rename to _sources/arrayfire.cuda.rst.txt diff --git a/_sources/arrayfire.cuda.txt b/_sources/arrayfire.cuda.txt new file mode 100644 index 000000000..f0f3a48b9 --- /dev/null +++ b/_sources/arrayfire.cuda.txt @@ -0,0 +1,7 @@ +arrayfire.cuda module +===================== + +.. automodule:: arrayfire.cuda + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.data.rst b/_sources/arrayfire.data.rst.txt similarity index 100% rename from docs/arrayfire.data.rst rename to _sources/arrayfire.data.rst.txt diff --git a/_sources/arrayfire.data.txt b/_sources/arrayfire.data.txt new file mode 100644 index 000000000..de208ff1d --- /dev/null +++ b/_sources/arrayfire.data.txt @@ -0,0 +1,7 @@ +arrayfire.data module +===================== + +.. automodule:: arrayfire.data + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.device.rst b/_sources/arrayfire.device.rst.txt similarity index 100% rename from docs/arrayfire.device.rst rename to _sources/arrayfire.device.rst.txt diff --git a/_sources/arrayfire.device.txt b/_sources/arrayfire.device.txt new file mode 100644 index 000000000..ad98bf639 --- /dev/null +++ b/_sources/arrayfire.device.txt @@ -0,0 +1,7 @@ +arrayfire.device module +======================= + +.. automodule:: arrayfire.device + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.features.rst b/_sources/arrayfire.features.rst.txt similarity index 100% rename from docs/arrayfire.features.rst rename to _sources/arrayfire.features.rst.txt diff --git a/_sources/arrayfire.features.txt b/_sources/arrayfire.features.txt new file mode 100644 index 000000000..44629c6f4 --- /dev/null +++ b/_sources/arrayfire.features.txt @@ -0,0 +1,7 @@ +arrayfire.features module +========================= + +.. automodule:: arrayfire.features + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.graphics.rst b/_sources/arrayfire.graphics.rst.txt similarity index 100% rename from docs/arrayfire.graphics.rst rename to _sources/arrayfire.graphics.rst.txt diff --git a/_sources/arrayfire.graphics.txt b/_sources/arrayfire.graphics.txt new file mode 100644 index 000000000..3a1505eae --- /dev/null +++ b/_sources/arrayfire.graphics.txt @@ -0,0 +1,7 @@ +arrayfire.graphics module +========================= + +.. automodule:: arrayfire.graphics + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.image.rst b/_sources/arrayfire.image.rst.txt similarity index 100% rename from docs/arrayfire.image.rst rename to _sources/arrayfire.image.rst.txt diff --git a/_sources/arrayfire.image.txt b/_sources/arrayfire.image.txt new file mode 100644 index 000000000..d4934b44b --- /dev/null +++ b/_sources/arrayfire.image.txt @@ -0,0 +1,7 @@ +arrayfire.image module +====================== + +.. automodule:: arrayfire.image + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.index.rst b/_sources/arrayfire.index.rst.txt similarity index 100% rename from docs/arrayfire.index.rst rename to _sources/arrayfire.index.rst.txt diff --git a/_sources/arrayfire.index.txt b/_sources/arrayfire.index.txt new file mode 100644 index 000000000..95c3dcde1 --- /dev/null +++ b/_sources/arrayfire.index.txt @@ -0,0 +1,7 @@ +arrayfire.index module +====================== + +.. automodule:: arrayfire.index + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.interop.rst b/_sources/arrayfire.interop.rst.txt similarity index 100% rename from docs/arrayfire.interop.rst rename to _sources/arrayfire.interop.rst.txt diff --git a/_sources/arrayfire.interop.txt b/_sources/arrayfire.interop.txt new file mode 100644 index 000000000..f7886aa07 --- /dev/null +++ b/_sources/arrayfire.interop.txt @@ -0,0 +1,7 @@ +arrayfire.interop module +======================== + +.. automodule:: arrayfire.interop + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.lapack.rst b/_sources/arrayfire.lapack.rst.txt similarity index 100% rename from docs/arrayfire.lapack.rst rename to _sources/arrayfire.lapack.rst.txt diff --git a/_sources/arrayfire.lapack.txt b/_sources/arrayfire.lapack.txt new file mode 100644 index 000000000..4f14e4c24 --- /dev/null +++ b/_sources/arrayfire.lapack.txt @@ -0,0 +1,7 @@ +arrayfire.lapack module +======================= + +.. automodule:: arrayfire.lapack + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.library.rst b/_sources/arrayfire.library.rst.txt similarity index 100% rename from docs/arrayfire.library.rst rename to _sources/arrayfire.library.rst.txt diff --git a/_sources/arrayfire.library.txt b/_sources/arrayfire.library.txt new file mode 100644 index 000000000..6c9c78d10 --- /dev/null +++ b/_sources/arrayfire.library.txt @@ -0,0 +1,7 @@ +arrayfire.library module +======================== + +.. automodule:: arrayfire.library + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.opencl.rst b/_sources/arrayfire.opencl.rst.txt similarity index 100% rename from docs/arrayfire.opencl.rst rename to _sources/arrayfire.opencl.rst.txt diff --git a/_sources/arrayfire.opencl.txt b/_sources/arrayfire.opencl.txt new file mode 100644 index 000000000..b4622b38d --- /dev/null +++ b/_sources/arrayfire.opencl.txt @@ -0,0 +1,7 @@ +arrayfire.opencl module +======================= + +.. automodule:: arrayfire.opencl + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/arrayfire.random.rst.txt b/_sources/arrayfire.random.rst.txt new file mode 100644 index 000000000..33c86f96b --- /dev/null +++ b/_sources/arrayfire.random.rst.txt @@ -0,0 +1,7 @@ +arrayfire.random module +========================= + +.. automodule:: arrayfire.random + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/arrayfire.random.txt b/_sources/arrayfire.random.txt new file mode 100644 index 000000000..33c86f96b --- /dev/null +++ b/_sources/arrayfire.random.txt @@ -0,0 +1,7 @@ +arrayfire.random module +========================= + +.. automodule:: arrayfire.random + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.rst b/_sources/arrayfire.rst.txt similarity index 91% rename from docs/arrayfire.rst rename to _sources/arrayfire.rst.txt index 2ccfd3b41..2951fcb3b 100644 --- a/docs/arrayfire.rst +++ b/_sources/arrayfire.rst.txt @@ -6,7 +6,7 @@ Introduction .. automodule:: arrayfire - Submodules +Submodules ---------- .. autosummary:: @@ -27,6 +27,8 @@ Introduction arrayfire.lapack arrayfire.library arrayfire.opencl + arrayfire.random + arrayfire.sparse arrayfire.signal arrayfire.statistics arrayfire.timer diff --git a/docs/arrayfire.signal.rst b/_sources/arrayfire.signal.rst.txt similarity index 100% rename from docs/arrayfire.signal.rst rename to _sources/arrayfire.signal.rst.txt diff --git a/_sources/arrayfire.signal.txt b/_sources/arrayfire.signal.txt new file mode 100644 index 000000000..ae06fdf9e --- /dev/null +++ b/_sources/arrayfire.signal.txt @@ -0,0 +1,7 @@ +arrayfire.signal module +======================= + +.. automodule:: arrayfire.signal + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/arrayfire.sparse.rst.txt b/_sources/arrayfire.sparse.rst.txt new file mode 100644 index 000000000..cc087885d --- /dev/null +++ b/_sources/arrayfire.sparse.rst.txt @@ -0,0 +1,7 @@ +arrayfire.sparse module +========================= + +.. automodule:: arrayfire.sparse + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/arrayfire.sparse.txt b/_sources/arrayfire.sparse.txt new file mode 100644 index 000000000..cc087885d --- /dev/null +++ b/_sources/arrayfire.sparse.txt @@ -0,0 +1,7 @@ +arrayfire.sparse module +========================= + +.. automodule:: arrayfire.sparse + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.statistics.rst b/_sources/arrayfire.statistics.rst.txt similarity index 100% rename from docs/arrayfire.statistics.rst rename to _sources/arrayfire.statistics.rst.txt diff --git a/_sources/arrayfire.statistics.txt b/_sources/arrayfire.statistics.txt new file mode 100644 index 000000000..a20ef21a2 --- /dev/null +++ b/_sources/arrayfire.statistics.txt @@ -0,0 +1,7 @@ +arrayfire.statistics module +=========================== + +.. automodule:: arrayfire.statistics + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.timer.rst b/_sources/arrayfire.timer.rst.txt similarity index 100% rename from docs/arrayfire.timer.rst rename to _sources/arrayfire.timer.rst.txt diff --git a/_sources/arrayfire.timer.txt b/_sources/arrayfire.timer.txt new file mode 100644 index 000000000..cb9cac2ed --- /dev/null +++ b/_sources/arrayfire.timer.txt @@ -0,0 +1,7 @@ +arrayfire.timer module +====================== + +.. automodule:: arrayfire.timer + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/arrayfire.txt b/_sources/arrayfire.txt new file mode 100644 index 000000000..2951fcb3b --- /dev/null +++ b/_sources/arrayfire.txt @@ -0,0 +1,36 @@ +ArrayFire Python Wrapper +======================== + +Introduction +--------------- + +.. automodule:: arrayfire + +Submodules +---------- + +.. autosummary:: + arrayfire.algorithm + arrayfire.arith + arrayfire.array + arrayfire.base + arrayfire.bcast + arrayfire.blas + arrayfire.cuda + arrayfire.data + arrayfire.device + arrayfire.features + arrayfire.graphics + arrayfire.image + arrayfire.index + arrayfire.interop + arrayfire.lapack + arrayfire.library + arrayfire.opencl + arrayfire.random + arrayfire.sparse + arrayfire.signal + arrayfire.statistics + arrayfire.timer + arrayfire.util + arrayfire.vision diff --git a/docs/arrayfire.util.rst b/_sources/arrayfire.util.rst.txt similarity index 100% rename from docs/arrayfire.util.rst rename to _sources/arrayfire.util.rst.txt diff --git a/_sources/arrayfire.util.txt b/_sources/arrayfire.util.txt new file mode 100644 index 000000000..c5192aeb8 --- /dev/null +++ b/_sources/arrayfire.util.txt @@ -0,0 +1,7 @@ +arrayfire.util module +===================== + +.. automodule:: arrayfire.util + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/arrayfire.vision.rst b/_sources/arrayfire.vision.rst.txt similarity index 100% rename from docs/arrayfire.vision.rst rename to _sources/arrayfire.vision.rst.txt diff --git a/_sources/arrayfire.vision.txt b/_sources/arrayfire.vision.txt new file mode 100644 index 000000000..d2f229a08 --- /dev/null +++ b/_sources/arrayfire.vision.txt @@ -0,0 +1,7 @@ +arrayfire.vision module +======================= + +.. automodule:: arrayfire.vision + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..2951fcb3b --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,36 @@ +ArrayFire Python Wrapper +======================== + +Introduction +--------------- + +.. automodule:: arrayfire + +Submodules +---------- + +.. autosummary:: + arrayfire.algorithm + arrayfire.arith + arrayfire.array + arrayfire.base + arrayfire.bcast + arrayfire.blas + arrayfire.cuda + arrayfire.data + arrayfire.device + arrayfire.features + arrayfire.graphics + arrayfire.image + arrayfire.index + arrayfire.interop + arrayfire.lapack + arrayfire.library + arrayfire.opencl + arrayfire.random + arrayfire.sparse + arrayfire.signal + arrayfire.statistics + arrayfire.timer + arrayfire.util + arrayfire.vision diff --git a/_sources/index.txt b/_sources/index.txt new file mode 100644 index 000000000..2951fcb3b --- /dev/null +++ b/_sources/index.txt @@ -0,0 +1,36 @@ +ArrayFire Python Wrapper +======================== + +Introduction +--------------- + +.. automodule:: arrayfire + +Submodules +---------- + +.. autosummary:: + arrayfire.algorithm + arrayfire.arith + arrayfire.array + arrayfire.base + arrayfire.bcast + arrayfire.blas + arrayfire.cuda + arrayfire.data + arrayfire.device + arrayfire.features + arrayfire.graphics + arrayfire.image + arrayfire.index + arrayfire.interop + arrayfire.lapack + arrayfire.library + arrayfire.opencl + arrayfire.random + arrayfire.sparse + arrayfire.signal + arrayfire.statistics + arrayfire.timer + arrayfire.util + arrayfire.vision diff --git a/docs/modules.rst b/_sources/modules.rst.txt similarity index 100% rename from docs/modules.rst rename to _sources/modules.rst.txt diff --git a/_sources/modules.txt b/_sources/modules.txt new file mode 100644 index 000000000..c5f5de84d --- /dev/null +++ b/_sources/modules.txt @@ -0,0 +1,7 @@ +arrayfire +========= + +.. toctree:: + :maxdepth: 4 + + arrayfire diff --git a/_static/ajax-loader.gif b/_static/ajax-loader.gif new file mode 100644 index 000000000..61faf8cab Binary files /dev/null and b/_static/ajax-loader.gif differ diff --git a/_static/alabaster.css b/_static/alabaster.css new file mode 100644 index 000000000..0eddaeb07 --- /dev/null +++ b/_static/alabaster.css @@ -0,0 +1,701 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Georgia, serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Georgia, serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: Georgia, serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +div.sphinxsidebar .badge { + border-bottom: none; +} + +div.sphinxsidebar .badge:hover { + border-bottom: none; +} + +/* To address an issue with donation coming after search */ +div.sphinxsidebar h3.donation { + margin-top: 10px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Georgia, serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: Georgia, serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + + +/* relbar */ + +.related { + line-height: 30px; + width: 100%; + font-size: 0.9rem; +} + +.related.top { + border-bottom: 1px solid #EEE; + margin-bottom: 20px; +} + +.related.bottom { + border-top: 1px solid #EEE; +} + +.related ul { + padding: 0; + margin: 0; + list-style: none; +} + +.related li { + display: inline; +} + +nav#rellinks { + float: right; +} + +nav#rellinks li+li:before { + content: "|"; +} + +nav#breadcrumbs li+li:before { + content: "\00BB"; +} + +/* Hide certain items when printing */ +@media print { + div.related { + display: none; + } +} \ No newline at end of file diff --git a/docs/arrayfire_logo_symbol.png b/_static/arrayfire_logo_symbol.png similarity index 100% rename from docs/arrayfire_logo_symbol.png rename to _static/arrayfire_logo_symbol.png diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..be19270e4 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,856 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/comment-bright.png b/_static/comment-bright.png new file mode 100644 index 000000000..15e27edb1 Binary files /dev/null and b/_static/comment-bright.png differ diff --git a/_static/comment-close.png b/_static/comment-close.png new file mode 100644 index 000000000..4d91bcf57 Binary files /dev/null and b/_static/comment-close.png differ diff --git a/_static/comment.png b/_static/comment.png new file mode 100644 index 000000000..dfbc0cbd5 Binary files /dev/null and b/_static/comment.png differ diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 000000000..2a924f1d6 --- /dev/null +++ b/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..61ac9d266 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,321 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..2dc73ca36 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '3.8.20210303', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/_static/down-pressed.png b/_static/down-pressed.png new file mode 100644 index 000000000..5756c8cad Binary files /dev/null and b/_static/down-pressed.png differ diff --git a/_static/down.png b/_static/down.png new file mode 100644 index 000000000..1b3bdad2c Binary files /dev/null and b/_static/down.png differ diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/graphviz.css b/_static/graphviz.css new file mode 100644 index 000000000..b340734c7 --- /dev/null +++ b/_static/graphviz.css @@ -0,0 +1,19 @@ +/* + * graphviz.css + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- graphviz extension. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +img.graphviz { + border: 0; + max-width: 100%; +} + +object.graphviz { + max-width: 100%; +} diff --git a/_static/jquery-1.11.1.js b/_static/jquery-1.11.1.js new file mode 100644 index 000000000..d4b67f7e6 --- /dev/null +++ b/_static/jquery-1.11.1.js @@ -0,0 +1,10308 @@ +/*! + * jQuery JavaScript Library v1.11.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-05-01T17:42Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "