(8635,18673,'2015-11-10 19:29:10','2015-11-10 19:29:10','Now that we’ve learned how to create arrays and apply simple operations to them, lets explore how we can re-order and modify them. Arrayfire offers several functions that can easily reformat the structures of arrays.\r\n<h5><a id=\"These_functions_are_2\"></a>These functions are:</h5>\r\n<ul>\r\n	<li><strong>flat()</strong> - flatten an array to one dimension</li>\r\n	<li><strong>flip()</strong> - flip an array along a dimension</li>\r\n	<li><strong>join()</strong> - join up to 4 arrays</li>\r\n	<li><strong>moddims()</strong> - change the dimensions of an array without changing the data</li>\r\n	<li><strong>reorder()</strong> - changes the dimension order within the array</li>\r\n	<li><strong>shift()</strong> - shifts data along a dimension</li>\r\n	<li><strong>tile()</strong> - repeats an array along a dimension</li>\r\n	<li><strong>transpose()</strong> - performs a matrix transpose</li>\r\n</ul>\r\nBelow, are several examples showing the details of each function. We’ll start by defining an example matrix:\r\n<h3><a id=\"flat_15\"></a>flat()</h3>\r\nThe <strong>flat()</strong> function flattens an array to one dimension.\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     4.0000     7.0000 \r\n    2.0000     5.0000     8.0000 \r\n    3.0000     6.0000     9.0000 \r\n\r\nflat(a) [9 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n    6.0000 \r\n    7.0000 \r\n    8.0000 \r\n    9.0000 \r\n</code></pre>\r\nThe flat function has the following overloads:\r\n<ul>\r\n	<li><strong>array af::flat(const array&amp; in)</strong> – flatten an array</li>\r\n	<li><strong>af_err af_flat(af_array* out, const af_array in)</strong> – C interface for flat() function</li>\r\n</ul>\r\n<h3><a id=\"flip_40\"></a>flip()</h3>\r\nThe <strong>flip()</strong> function flips the contents of an array along a chosen dimension.\r\n<pre><code>a [5 2 1 1]\r\n    1.0000     6.0000 \r\n    2.0000     7.0000 \r\n    3.0000     8.0000 \r\n    4.0000     9.0000 \r\n    5.0000    10.0000 \r\n\r\nflip(a, 0) [5 2 1 1]\r\n    5.0000    10.0000 \r\n    4.0000     9.0000 \r\n    3.0000     8.0000 \r\n    2.0000     7.0000 \r\n    1.0000     6.0000 \r\n\r\nflip(a, 1) [5 2 1 1]\r\n    6.0000     1.0000 \r\n    7.0000     2.0000 \r\n    8.0000     3.0000 \r\n    9.0000     4.0000 \r\n   10.0000     5.0000 </code></pre>\r\nThe flip function has the following overloads:\r\n<ul>\r\n	<li><strong>flip (const array &amp;in, const unsigned dim)</strong> – flips an array along a dimension</li>\r\n	<li><strong>af_flip (af_array *out, const af_array in, const unsigned dim)</strong> – C interface for flip()</li>\r\n</ul>\r\n<h3><a id=\"join_68\"></a>join()</h3>\r\nThe <strong>join()</strong> function can join up to 4 arrays together.\r\n<pre><code>a [5 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n\r\njoin(0, a, a) [10 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n\r\njoin(1, a, a) [5 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n    4.0000     4.0000 \r\n    5.0000     5.0000 </code></pre>\r\nThe join function has several overloads:\r\n<ul>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second)</strong> – Joins 2 arrays along a dimension</li>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second, const array &amp;third)</strong> – Joins 3 arrays along a dimension.</li>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second, const array &amp;third, const array &amp;fourth)</strong> – Joins 4 arrays along a dimension</li>\r\n	<li><strong>array af_join (af_array *out, const int dim, const af_array first, const af_array second)</strong> – C interface function to join 2 arrays along a dimension.</li>\r\n	<li><strong>af_err af_join_many (af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)</strong> – C interface function to join up to 10 arrays along a dimension.</li>\r\n</ul>\r\n<h3><a id=\"moddims_108\"></a>moddims()</h3>\r\nThe <strong>moddims()</strong> function changes the dimensions of an array without changing its data or order. It is important to remember that the function only modifies the <em>metadata</em> associated with the array and does not actually modify the content of the array.\r\n<pre><code>a [8 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n\r\nmoddims(a, new_dims) [2 4 1 1]\r\n    1.0000     1.0000     1.0000     1.0000 \r\n    2.0000     2.0000     2.0000     2.0000 \r\n\r\nmoddims(a, a.elements(), 1, 1, 1) [8 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n</code></pre>\r\nThe moddims function has several overloads:\r\n<ul>\r\n	<li><strong>array moddims (const array &amp;in, const unsigned ndims, const dim_t *const dims)</strong> – mods number of dimensions to match <em>ndims</em> as specidied in the array <em>dims</em></li>\r\n	<li><strong>array moddims (const array &amp;in, const dim4 &amp;dims)</strong> – mods dimensions as specified by <em>dims</em></li>\r\n	<li><strong>array moddims (const array &amp;in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)</strong> – mods dimensions of an array</li>\r\n	<li><strong>af_err af_moddims (af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)</strong> – C interface to mod dimensions of an array</li>\r\n</ul>\r\n<h3><a id=\"reorder_141\"></a>reorder()</h3>\r\nThe <strong>reorder()</strong> function changes the order of the dimensions within the array. This requires actually altering the underlying data of the array.\r\n<pre><code>a [2 2 3 1]\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n\r\nreorder(a, 1, 0, 2) [2 2 3 1]  //equivalent to a transpose\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n\r\nreorder(a, 2, 0, 1) [3 2 2 1]\r\n    1.0000     2.0000 \r\n    1.0000     2.0000 \r\n    1.0000     2.0000 \r\n\r\n    3.0000     4.0000 \r\n    3.0000     4.0000 \r\n    3.0000     4.0000 \r\n</code></pre>\r\nThe reorder function the following several overloads:\r\n<ul>\r\n	<li><strong>array reorder (const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)</strong> – Reorders dimensions of an array</li>\r\n	<li><strong>af_reorder (af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for reordering function</li>\r\n</ul>\r\n<h3><a id=\"shift_180\"></a>shift()</h3>\r\nThe <strong>shift()</strong> function shifts data in a circular buffer fashion along a chosen dimension.\r\n<pre><code>a [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n    3.0000     4.0000     5.0000     1.0000     2.0000 \r\n    3.0000     4.0000     5.0000     1.0000     2.0000 \r\n\r\nshift(a, 0, 2 ) [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n\r\nshift(a, -1, 2 ) [3 5 1 1]\r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n</code></pre>\r\nThe shift function has the following overloads:\r\n<ul>\r\n	<li><strong>array shift (const array &amp;in, const int x, const int y=0, const int z=0, const int w=0)</strong> – Shifts array along specified dimensions</li>\r\n	<li><strong>af_err af_shift (af_array *out, const af_array in, const int x, const int y, const int z, const int w)</strong> – C interface for shifting an array</li>\r\n</ul>\r\n<h3><a id=\"tile_203\"></a>tile()</h3>\r\nThe <strong>tile()</strong> function repeats an array along a dimension\r\n<pre><code>a [3 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n\r\ntile(a, 2) [6 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n\r\ntile(a, 2, 2) [6 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\naf::dim4 tile_dims(1, 2, 3);\r\ntile(a, tile_dims) [3 2 3 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000</code></pre>\r\nThe tile function has several overloads:\r\n<ul>\r\n	<li><strong>array tile (const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)</strong> – Tiles array along specified dimensions</li>\r\n	<li><strong>array tile (const array &amp;in, const dim4 &amp;dims)</strong> – Tile an array according to a dim4 object</li>\r\n	<li><strong>af_err af_tile (af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for tiling an array</li>\r\n</ul>\r\n<h3><a id=\"transpose_247\"></a>transpose()</h3>\r\nThe <strong>transpose()</strong> function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     3.0000     3.0000 \r\n    2.0000     1.0000     3.0000 \r\n    2.0000     2.0000     1.0000 \r\n\r\ntranspose(a) [3 3 1 1]\r\n    1.0000     2.0000     2.0000 \r\n    3.0000     1.0000     2.0000 \r\n    3.0000     3.0000     1.0000 </code></pre>\r\nThe transpose function has several overloads:\r\n<ul>\r\n	<li><strong>array transpose (const array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix.</li>\r\n	<li><strong>void transposeInPlace (array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix in-place.</li>\r\n	<li><strong>af_err af_transpose (af_array *out, af_array in, const bool conjugate)</strong> – C interface to transpose a matrix.</li>\r\n	<li><strong>af_err af_transpose_inplace (af_array in, const bool conjugate)</strong> – C interface to transpose a matrix in-place.</li>\r\n</ul>\r\n<h1><a id=\"Combining_reordering_functions_to_enumerate_grid_coordinates_270\"></a>Combining re-ordering functions to enumerate grid coordinates</h1>\r\nBy using a combination of the array restructuring functions, we can quickly code complex manipulation patterns with a few lines of code. For example, consider generating <em>(x,y)</em> coordinates for a grid where each axis goes from <em>1 to n</em>. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.\r\n<pre><code>unsigned n=3;\r\naf::array a = join(1, \r\n                tile(seq(1, n), n), \r\n                flat( transpose(tile(seq(1, n), 1, n)) )\r\n            );\r\na [9 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     1.0000 \r\n    3.0000     1.0000 \r\n    1.0000     2.0000 \r\n    2.0000     2.0000 \r\n    3.0000     2.0000 \r\n    1.0000     3.0000 \r\n    2.0000     3.0000 \r\n    3.0000     3.0000 </code></pre>\r\n<h1><a id=\"Conclusion_289\"></a>Conclusion</h1>\r\nFunctions provided by arrayfire offer ease and flexibility for efficiently manipulating the structure of arrays. The provided functions can be used as building blocks to generate, shift, or prepare data to any form imaginable!\r\n\r\n&nbsp;','Manipulating and restructuring arrays','','inherit','open','closed','','8633-revision-v1','','','2015-11-10 19:29:10','2015-11-10 19:29:10','',8633,'http://sandbox.arrayfire.com/8633-revision-v1/',0,'revision','',0),(8636,18673,'2015-11-10 19:29:55','2015-11-10 19:29:55','Now that we’ve learned how to create arrays and apply simple operations to them, lets explore how we can re-order and modify them. Arrayfire offers several functions that can easily reformat the structures of arrays.\r\n<h5><a id=\"These_functions_are_2\"></a>These functions are:</h5>\r\n<ul>\r\n	<li><strong>flat()</strong> - flatten an array to one dimension</li>\r\n	<li><strong>flip()</strong> - flip an array along a dimension</li>\r\n	<li><strong>join()</strong> - join up to 4 arrays</li>\r\n	<li><strong>moddims()</strong> - change the dimensions of an array without changing the data</li>\r\n	<li><strong>reorder()</strong> - changes the dimension order within the array</li>\r\n	<li><strong>shift()</strong> - shifts data along a dimension</li>\r\n	<li><strong>tile()</strong> - repeats an array along a dimension</li>\r\n	<li><strong>transpose()</strong> - performs a matrix transpose</li>\r\n</ul>\r\nBelow, are several examples showing the details of each function. We’ll start by defining an example matrix:\r\n<h3><a id=\"flat_15\"></a>flat()</h3>\r\nThe <strong>flat()</strong> function flattens an array to one dimension.\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     4.0000     7.0000 \r\n    2.0000     5.0000     8.0000 \r\n    3.0000     6.0000     9.0000 \r\n\r\nflat(a) [9 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n    6.0000 \r\n    7.0000 \r\n    8.0000 \r\n    9.0000 \r\n</code></pre>\r\nThe flat function has the following overloads:\r\n<ul>\r\n	<li><strong>array af::flat(const array&amp; in)</strong> – flatten an array</li>\r\n	<li><strong>af_err af_flat(af_array* out, const af_array in)</strong> – C interface for flat() function</li>\r\n</ul>\r\n<h3><a id=\"flip_40\"></a>flip()</h3>\r\nThe <strong>flip()</strong> function flips the contents of an array along a chosen dimension.\r\n<pre><code>a [5 2 1 1]\r\n    1.0000     6.0000 \r\n    2.0000     7.0000 \r\n    3.0000     8.0000 \r\n    4.0000     9.0000 \r\n    5.0000    10.0000 \r\n\r\nflip(a, 0) [5 2 1 1]\r\n    5.0000    10.0000 \r\n    4.0000     9.0000 \r\n    3.0000     8.0000 \r\n    2.0000     7.0000 \r\n    1.0000     6.0000 \r\n\r\nflip(a, 1) [5 2 1 1]\r\n    6.0000     1.0000 \r\n    7.0000     2.0000 \r\n    8.0000     3.0000 \r\n    9.0000     4.0000 \r\n   10.0000     5.0000 </code></pre>\r\nThe flip function has the following overloads:\r\n<ul>\r\n	<li><strong>flip (const array &amp;in, const unsigned dim)</strong> – flips an array along a dimension</li>\r\n	<li><strong>af_flip (af_array *out, const af_array in, const unsigned dim)</strong> – C interface for flip()</li>\r\n</ul>\r\n<h3><a id=\"join_68\"></a>join()</h3>\r\nThe <strong>join()</strong> function can join up to 4 arrays together.\r\n<pre><code>a [5 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n\r\njoin(0, a, a) [10 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    4.0000 \r\n    5.0000 \r\n\r\njoin(1, a, a) [5 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n    4.0000     4.0000 \r\n    5.0000     5.0000 </code></pre>\r\nThe join function has several overloads:\r\n<ul>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second)</strong> – Joins 2 arrays along a dimension</li>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second, const array &amp;third)</strong> – Joins 3 arrays along a dimension.</li>\r\n	<li><strong>array join (const int dim, const array &amp;first, const array &amp;second, const array &amp;third, const array &amp;fourth)</strong> – Joins 4 arrays along a dimension</li>\r\n	<li><strong>array af_join (af_array *out, const int dim, const af_array first, const af_array second)</strong> – C interface function to join 2 arrays along a dimension.</li>\r\n	<li><strong>af_err af_join_many (af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)</strong> – C interface function to join up to 10 arrays along a dimension.</li>\r\n</ul>\r\n<h3><a id=\"moddims_108\"></a>moddims()</h3>\r\nThe <strong>moddims()</strong> function changes the dimensions of an array without changing its data or order. It is important to remember that the function only modifies the <em>metadata</em> associated with the array and does not actually modify the content of the array.\r\n<pre><code>a [8 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n\r\nmoddims(a, new_dims) [2 4 1 1]\r\n    1.0000     1.0000     1.0000     1.0000 \r\n    2.0000     2.0000     2.0000     2.0000 \r\n\r\nmoddims(a, a.elements(), 1, 1, 1) [8 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n    1.0000 \r\n    2.0000 \r\n</code></pre>\r\nThe moddims function has several overloads:\r\n<ul>\r\n	<li><strong>array moddims (const array &amp;in, const unsigned ndims, const dim_t *const dims)</strong> – mods number of dimensions to match <em>ndims</em> as specidied in the array <em>dims</em></li>\r\n	<li><strong>array moddims (const array &amp;in, const dim4 &amp;dims)</strong> – mods dimensions as specified by <em>dims</em></li>\r\n	<li><strong>array moddims (const array &amp;in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)</strong> – mods dimensions of an array</li>\r\n	<li><strong>af_err af_moddims (af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)</strong> – C interface to mod dimensions of an array</li>\r\n</ul>\r\n<h3><a id=\"reorder_141\"></a>reorder()</h3>\r\nThe <strong>reorder()</strong> function changes the order of the dimensions within the array. This requires actually altering the underlying data of the array.\r\n<pre><code>a [2 2 3 1]\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n    1.0000     3.0000 \r\n    2.0000     4.0000 \r\n\r\n\r\nreorder(a, 1, 0, 2) [2 2 3 1]  //equivalent to a transpose\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n    1.0000     2.0000 \r\n    3.0000     4.0000 \r\n\r\n\r\nreorder(a, 2, 0, 1) [3 2 2 1]\r\n    1.0000     2.0000 \r\n    1.0000     2.0000 \r\n    1.0000     2.0000 \r\n\r\n    3.0000     4.0000 \r\n    3.0000     4.0000 \r\n    3.0000     4.0000 \r\n</code></pre>\r\nThe reorder function the following several overloads:\r\n<ul>\r\n	<li><strong>array reorder (const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)</strong> – Reorders dimensions of an array</li>\r\n	<li><strong>af_reorder (af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for reordering function</li>\r\n</ul>\r\n<h3><a id=\"shift_180\"></a>shift()</h3>\r\nThe <strong>shift()</strong> function shifts data in a circular buffer fashion along a chosen dimension.\r\n<pre><code>a [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n    3.0000     4.0000     5.0000     1.0000     2.0000 \r\n    3.0000     4.0000     5.0000     1.0000     2.0000 \r\n\r\nshift(a, 0, 2 ) [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n\r\nshift(a, -1, 2 ) [3 5 1 1]\r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    1.0000     2.0000     3.0000     4.0000     5.0000 \r\n    0.0000     0.0000     0.0000     0.0000     0.0000 \r\n</code></pre>\r\nThe shift function has the following overloads:\r\n<ul>\r\n	<li><strong>array shift (const array &amp;in, const int x, const int y=0, const int z=0, const int w=0)</strong> – Shifts array along specified dimensions</li>\r\n	<li><strong>af_err af_shift (af_array *out, const af_array in, const int x, const int y, const int z, const int w)</strong> – C interface for shifting an array</li>\r\n</ul>\r\n<h3><a id=\"tile_203\"></a>tile()</h3>\r\nThe <strong>tile()</strong> function repeats an array along a dimension\r\n<pre><code>a [3 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n\r\ntile(a, 2) [6 1 1 1]\r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n    1.0000 \r\n    2.0000 \r\n    3.0000 \r\n\r\ntile(a, 2, 2) [6 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\naf::dim4 tile_dims(1, 2, 3);\r\ntile(a, tile_dims) [3 2 3 1]\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000 \r\n\r\n    1.0000     1.0000 \r\n    2.0000     2.0000 \r\n    3.0000     3.0000</code></pre>\r\nThe tile function has several overloads:\r\n<ul>\r\n	<li><strong>array tile (const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)</strong> – Tiles array along specified dimensions</li>\r\n	<li><strong>array tile (const array &amp;in, const dim4 &amp;dims)</strong> – Tile an array according to a dim4 object</li>\r\n	<li><strong>af_err af_tile (af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for tiling an array</li>\r\n</ul>\r\n<h3><a id=\"transpose_247\"></a>transpose()</h3>\r\nThe <strong>transpose()</strong> function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     3.0000     3.0000 \r\n    2.0000     1.0000     3.0000 \r\n    2.0000     2.0000     1.0000 \r\n\r\ntranspose(a) [3 3 1 1]\r\n    1.0000     2.0000     2.0000 \r\n    3.0000     1.0000     2.0000 \r\n    3.0000     3.0000     1.0000 </code></pre>\r\nThe transpose function has several overloads:\r\n<ul>\r\n	<li><strong>array transpose (const array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix.</li>\r\n	<li><strong>void transposeInPlace (array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix in-place.</li>\r\n	<li><strong>af_err af_transpose (af_array *out, af_array in, const bool conjugate)</strong> – C interface to transpose a matrix.</li>\r\n	<li><strong>af_err af_transpose_inplace (af_array in, const bool conjugate)</strong> – C interface to transpose a matrix in-place.</li>\r\n</ul>\r\n<h3><a id=\"Combining_reordering_functions_to_enumerate_grid_coordinates_270\"></a>Combining re-ordering functions to enumerate grid coordinates</h3>\r\nBy using a combination of the array restructuring functions, we can quickly code complex manipulation patterns with a few lines of code. For example, consider generating <em>(x,y)</em> coordinates for a grid where each axis goes from <em>1 to n</em>. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.\r\n<pre><code>unsigned n=3;\r\naf::array a = join(1, \r\n                tile(seq(1, n), n), \r\n                flat( transpose(tile(seq(1, n), 1, n)) )\r\n            );\r\na [9 2 1 1]\r\n    1.0000     1.0000 \r\n    2.0000     1.0000 \r\n    3.0000     1.0000 \r\n    1.0000     2.0000 \r\n    2.0000     2.0000 \r\n    3.0000     2.0000 \r\n    1.0000     3.0000 \r\n    2.0000     3.0000 \r\n    3.0000     3.0000 </code></pre>\r\n<h3><a id=\"Conclusion_289\"></a>Conclusion</h3>\r\nFunctions provided by arrayfire offer ease and flexibility for efficiently manipulating the structure of arrays. The provided functions can be used as building blocks to generate, shift, or prepare data to any form imaginable!\r\n\r\n&nbsp;','Manipulating and restructuring arrays','','inherit','open','closed','','8633-revision-v1','','','2015-11-10 19:29:55','2015-11-10 19:29:55','',8633,'http://sandbox.arrayfire.com/8633-revision-v1/',0,'revision','',0),(8637,18673,'2015-11-11 15:22:22','2015-11-11 15:22:22','Now that we’ve learned how to create arrays and apply simple operations to them, lets explore how we can re-order and modify them. Arrayfire offers several functions that can easily reformat the structures of arrays.\r\n<h5><a id=\"These_functions_are_2\"></a>These functions are:</h5>\r\n<ul>\r\n	<li><strong>flat()</strong> - flatten an array to one dimension</li>\r\n	<li><strong>flip()</strong> - flip an array along a dimension</li>\r\n	<li><strong>join()</strong> - join up to 4 arrays</li>\r\n	<li><strong>moddims()</strong> - change the dimensions of an array without changing the data</li>\r\n	<li><strong>reorder()</strong> - changes the dimension order within the array</li>\r\n	<li><strong>shift()</strong> - shifts data along a dimension</li>\r\n	<li><strong>tile()</strong> - repeats an array along a dimension</li>\r\n	<li><strong>transpose()</strong> - performs a matrix transpose</li>\r\n</ul>\r\nBelow, are several examples showing the details of each function. We’ll start by defining an example matrix:\r\n<h3><a id=\"flat_15\"></a>flat()</h3>\r\n<p>The <strong>flat()</strong> function flattens an array to one dimension.</p>\r\n<pre><code>a [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">7.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">5.0000</span>     <span class=\"hljs-number\">8.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">6.0000</span>     <span class=\"hljs-number\">9.0000</span>\r\n\r\nflat(a) [<span class=\"hljs-number\">9</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>\r\n    <span class=\"hljs-number\">6.0000</span>\r\n    <span class=\"hljs-number\">7.0000</span>\r\n    <span class=\"hljs-number\">8.0000</span>\r\n    <span class=\"hljs-number\">9.0000</span>\r\n\r\n</code></pre>\r\n<p>The flat function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flat(const array&amp; in)</strong> – flatten an array</li>\r\n<li><strong>af_err af_flat(af_array* out, const af_array in)</strong> – C interface for flat() function</li>\r\n</ul>\r\n<h3><a id=\"flip_37\"></a>flip()</h3>\r\n<p>The <strong>flip()</strong> function flips the contents of an array along a chosen dimension.</p>\r\n<pre><code>a [<span class=\"hljs-number\">5</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">6.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">7.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">8.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">9.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>    <span class=\"hljs-number\">10.0000</span>\r\n\r\nflip(a, <span class=\"hljs-number\">0</span>) [<span class=\"hljs-number\">5</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">5.0000</span>    <span class=\"hljs-number\">10.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">9.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">8.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">7.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">6.0000</span>\r\n\r\nflip(a, <span class=\"hljs-number\">1</span>) [<span class=\"hljs-number\">5</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">6.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">7.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">8.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">9.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n   <span class=\"hljs-number\">10.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n</code></pre>\r\n<p>The flip function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flip(const array &amp;in, const unsigned dim)</strong> – flips an array along a dimension</li>\r\n<li><strong>af_err af_flip(af_array *out, const af_array in, const unsigned dim)</strong> – C interface for flip()</li>\r\n</ul>\r\n<h3><a id=\"join_65\"></a>join()</h3>\r\n<p>The <strong>join()</strong> function can join up to 4 arrays together.</p>\r\n<pre><code>a [<span class=\"hljs-number\">5</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>\r\n\r\njoin(<span class=\"hljs-number\">0</span>, a, a) [<span class=\"hljs-number\">10</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>\r\n\r\njoin(<span class=\"hljs-number\">1</span>, a, a) [<span class=\"hljs-number\">5</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">5.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n</code></pre>\r\n<p>The join function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second)</strong> – Joins 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third)</strong> – Joins 3 arrays along a dimension.</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third, const array &amp;fourth)</strong> – Joins 4 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join(af_array *out, const int dim, const af_array first, const af_array second)</strong> – C interface function to join 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join_many(af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)</strong> – C interface function to join up to 10 arrays along a dimension</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"moddims_105\"></a>moddims()</h3>\r\n<p>The <strong>moddims()</strong> function changes the dimensions of an array without changing its data or order. It is important to remember that the function only modifies the <em>metadata</em> associated with the array and does not actually modify the content of the array.</p>\r\n<pre><code>a [<span class=\"hljs-number\">8</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n\r\naf::<span class=\"hljs-function\">dim4 <span class=\"hljs-title\">new_dims</span><span class=\"hljs-params\">(<span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">4</span>)</span></span>;\r\nmoddims(a, new_dims) [<span class=\"hljs-number\">2</span> <span class=\"hljs-number\">4</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n\r\nmoddims(a, a.elements(), <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">1</span>) [<span class=\"hljs-number\">8</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n</code></pre>\r\n<p>The moddims function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::moddims(const array &amp;in, const unsigned ndims, const dim_t *const dims)</strong> – mods number of dimensions to match <em>ndims</em> as specidied in the array <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim4 &amp;dims)</strong> – mods dimensions as specified by <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)</strong> – mods dimensions of an array</li>\r\n<li><strong>af_err af_moddims(af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)</strong> – C interface to mod dimensions of an array</li>\r\n</ul>\r\n<h3><a id=\"reorder_139\"></a>reorder()</h3>\r\n<p>The <strong>reorder()</strong> function changes the order of the dimensions within the array. This actually alters the underlying data of the array.</p>\r\n<pre><code>a [<span class=\"hljs-number\">2</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n\r\nreorder(a, <span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">2</span>) [<span class=\"hljs-number\">2</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span>]  <span class=\"hljs-comment\">//equivalent to a transpose</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n\r\n\r\nreorder(a, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">1</span>) [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>\r\n</code></pre>\r\n<p>The reorder function the following several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::reorder(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)</strong> – Reorders dimensions of an array</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_reorder(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for reordering function</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"shift_178\"></a>shift()</h3>\r\n<p>The <strong>shift()</strong> function shifts data in a circular buffer fashion along a chosen dimension.</p>\r\n<pre><code>a [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">5</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n\r\nshift(a, <span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">2</span> ) [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">5</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n\r\nshift(a, -<span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span> ) [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">5</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">4.0000</span>     <span class=\"hljs-number\">5.0000</span>\r\n    <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>     <span class=\"hljs-number\">0.0000</span>\r\n</code></pre>\r\n<p>The shift function has the following overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::shift(const array &amp;in, const int x, const int y=0, const int z=0, const int w=0)</strong> – Shifts array along specified dimensions</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_shift(af_array *out, const af_array in, const int x, const int y, const int z, const int w)</strong> – C interface for shifting an array</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"tile_201\"></a>tile()</h3>\r\n<p>The <strong>tile()</strong> function repeats an array along a dimension</p>\r\n<pre><code>a [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n\r\ntile(a, <span class=\"hljs-number\">2</span>) [<span class=\"hljs-number\">6</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>\r\n\r\ntile(a, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">2</span>) [<span class=\"hljs-number\">6</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n\r\naf::<span class=\"hljs-function\">dim4 <span class=\"hljs-title\">tile_dims</span><span class=\"hljs-params\">(<span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">2</span>, <span class=\"hljs-number\">3</span>)</span></span>;\r\ntile(a, tile_dims) [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n\r\n</code></pre>\r\n<p>The tile function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::tile(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)</strong>  –  Tiles array along specified dimensions</li>\r\n<li><strong>array af::tile(const array &amp;in, const dim4 &amp;dims)</strong>  –  Tile an array according to a dim4 object</li>\r\n<li><strong>af_err af_tile(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong>  –  C interface for tiling an array</li>\r\n</ul>\r\n<h3><a id=\"transpose_245\"></a>transpose()</h3>\r\n<p>The <strong>transpose()</strong> function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.</p>\r\n<pre><code>a [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n\r\ntranspose(a) [<span class=\"hljs-number\">3</span> <span class=\"hljs-number\">3</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n\r\n</code></pre>\r\n<p>The transpose function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::transpose(const array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>void af::transposeInPlace(array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix in-place.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose(af_array *out, af_array in, const bool conjugate)</strong> – C interface to transpose a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose_inplace(af_array in, const bool conjugate)</strong> – C interface to transpose a matrix in-place.</p>\r\n</li>\r\n</ul>\r\n<p>[array()](\\ref af::array) can be used to create a (shallow) copy of a matrix\r\nwith different dimensions.  The number of elements must remain the same as\r\nthe original array.</p>\r\n<p>\\snippet test/matrix_manipulation.cpp ex_matrix_manipulation_moddims</p>\r\n<p>The [T()](\\ref af::array::T) and [H()](\\ref af::array::H) methods can be\r\nused to form the [matrix or vector transpose](\\ref af::array::T) .</p>\r\n<p>\\snippet test/matrix_manipulation.cpp ex_matrix_manipulation_transpose</p>\r\n<h3><a id=\"Combining_reordering_functions_to_enumerate_grid_coordinates_279\"></a>Combining re-ordering functions to enumerate grid coordinates</h3>\r\n<p>By using a combination of the array restructuring functions, we can quickly code complex manipulation patterns with a few lines of code. For example, consider generating <em>(x,y)</em> coordinates for a grid where each axis goes from <em>1 to n</em>. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.</p>\r\n<pre><code><span class=\"hljs-keyword\">unsigned</span> n=<span class=\"hljs-number\">3</span>;\r\naf::<span class=\"hljs-built_in\">array</span> xy = join(<span class=\"hljs-number\">1</span>\r\n                tile(seq(<span class=\"hljs-number\">1</span>, n), n)\r\n                flat( transpose(tile(seq(<span class=\"hljs-number\">1</span>, n), <span class=\"hljs-number\">1</span>, n)) )\r\n                   );\r\nxy [<span class=\"hljs-number\">9</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n</code></pre>\r\n<h3><a id=\"Conclusion_298\"></a>Conclusion</h3>\r\n<p>Functions provided by arrayfire offer ease and flexibility for efficiently manipulating the structure of arrays. The provided functions can be used as building blocks to generate, shift, or prepare data to any form imaginable!</p>\r\n\r\n','Manipulating and restructuring arrays','','inherit','open','closed','','8633-revision-v1','','','2015-11-11 15:22:22','2015-11-11 15:22:22','',8633,'http://sandbox.arrayfire.com/8633-revision-v1/',0,'revision','',0),(8638,18673,'2015-11-11 15:30:08','2015-11-11 15:30:08','Now that we’ve learned how to create arrays and apply simple operations to them, lets explore how we can re-order and modify them. Arrayfire offers several functions that can easily reformat the structures of arrays.\r\n<h5><a id=\"These_functions_are_2\"></a>These functions are:</h5>\r\n<ul>\r\n	<li><strong>flat()</strong> - flatten an array to one dimension</li>\r\n	<li><strong>flip()</strong> - flip an array along a dimension</li>\r\n	<li><strong>join()</strong> - join up to 4 arrays</li>\r\n	<li><strong>moddims()</strong> - change the dimensions of an array without changing the data</li>\r\n	<li><strong>reorder()</strong> - changes the dimension order within the array</li>\r\n	<li><strong>shift()</strong> - shifts data along a dimension</li>\r\n	<li><strong>tile()</strong> - repeats an array along a dimension</li>\r\n	<li><strong>transpose()</strong> - performs a matrix transpose</li>\r\n</ul>\r\nBelow, are several examples showing the details of each function. We’ll start by defining an example matrix:\r\n<h3><a id=\"flat_15\"></a>flat()</h3>\r\n<p>The <strong>flat()</strong> function flattens an array to one dimension.</p>\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     4.0000     7.0000\r\n    2.0000     5.0000     8.0000\r\n    3.0000     6.0000     9.0000\r\n\r\nflat(a) [9 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n    6.0000\r\n    7.0000\r\n    8.0000\r\n    9.0000</code></pre>\r\n<p>The flat function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flat(const array&amp; in)</strong> – flatten an array</li>\r\n<li><strong>af_err af_flat(af_array* out, const af_array in)</strong> – C interface for flat() function</li>\r\n</ul>\r\n<h3><a id=\"flip_37\"></a>flip()</h3>\r\n<p>The <strong>flip()</strong> function flips the contents of an array along a chosen dimension.</p>\r\n<pre><code>a [5 2 1 1]\r\n    1.0000     6.0000\r\n    2.0000     7.0000\r\n    3.0000     8.0000\r\n    4.0000     9.0000\r\n    5.0000    10.0000\r\n\r\nflip(a, 0) [5 2 1 1]\r\n    5.0000    10.0000\r\n    4.0000     9.0000\r\n    3.0000     8.0000\r\n    2.0000     7.0000\r\n    1.0000     6.0000\r\n\r\nflip(a, 1) [5 2 1 1]\r\n    6.0000     1.0000\r\n    7.0000     2.0000\r\n    8.0000     3.0000\r\n    9.0000     4.0000\r\n   10.0000     5.0000</code></pre>\r\n<p>The flip function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flip(const array &amp;in, const unsigned dim)</strong> – flips an array along a dimension</li>\r\n<li><strong>af_err af_flip(af_array *out, const af_array in, const unsigned dim)</strong> – C interface for flip()</li>\r\n</ul>\r\n<h3><a id=\"join_65\"></a>join()</h3>\r\n<p>The <strong>join()</strong> function can join up to 4 arrays together.</p>\r\n<pre><code>a [5 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n\r\njoin(0, a, a) [10 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n\r\njoin(1, a, a) [5 2 1 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n    4.0000     4.0000\r\n    5.0000     5.0000</code></pre>\r\n<p>The join function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second)</strong> – Joins 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third)</strong> – Joins 3 arrays along a dimension.</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third, const array &amp;fourth)</strong> – Joins 4 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join(af_array *out, const int dim, const af_array first, const af_array second)</strong> – C interface function to join 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join_many(af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)</strong> – C interface function to join up to 10 arrays along a dimension</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"moddims_105\"></a>moddims()</h3>\r\n<p>The <strong>moddims()</strong> function changes the dimensions of an array without changing its data or order. It is important to remember that the function only modifies the <em>metadata</em> associated with the array and does not actually modify the content of the array.</p>\r\n<pre><code>a [8 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n\r\naf::dim4 new_dims(2, 4);\r\nmoddims(a, new_dims) [2 4 1 1]\r\n    1.0000     1.0000     1.0000     1.0000\r\n    2.0000     2.0000     2.0000     2.0000\r\n\r\nmoddims(a, a.elements(), 1, 1, 1) [8 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000</code></pre>\r\n<p>The moddims function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::moddims(const array &amp;in, const unsigned ndims, const dim_t *const dims)</strong> – mods number of dimensions to match <em>ndims</em> as specidied in the array <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim4 &amp;dims)</strong> – mods dimensions as specified by <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)</strong> – mods dimensions of an array</li>\r\n<li><strong>af_err af_moddims(af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)</strong> – C interface to mod dimensions of an array</li>\r\n</ul>\r\n<h3><a id=\"reorder_139\"></a>reorder()</h3>\r\n<p>The <strong>reorder()</strong> function changes the order of the dimensions within the array. This actually alters the underlying data of the array.</p>\r\n<pre><code>a [2 2 3 1]\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n\r\nreorder(a, 1, 0, 2) [2 2 3 1]  //equivalent to a transpose\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n\r\nreorder(a, 2, 0, 1) [3 2 2 1]\r\n    1.0000     2.0000\r\n    1.0000     2.0000\r\n    1.0000     2.0000\r\n\r\n    3.0000     4.0000\r\n    3.0000     4.0000\r\n    3.0000     4.0000</code></pre>\r\n<p>The reorder function the following several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::reorder(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)</strong> – Reorders dimensions of an array</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_reorder(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for reordering function</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"shift_178\"></a>shift()</h3>\r\n<p>The <strong>shift()</strong> function shifts data in a circular buffer fashion along a chosen dimension.</p>\r\n<pre><code>a [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000\r\n    3.0000     4.0000     5.0000     1.0000     2.0000\r\n    3.0000     4.0000     5.0000     1.0000     2.0000\r\n\r\nshift(a, 0, 2 ) [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n\r\nshift(a, -1, 2 ) [3 5 1 1]\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    0.0000     0.0000     0.0000     0.0000     0.0000</code></pre>\r\n<p>The shift function has the following overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::shift(const array &amp;in, const int x, const int y=0, const int z=0, const int w=0)</strong> – Shifts array along specified dimensions</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_shift(af_array *out, const af_array in, const int x, const int y, const int z, const int w)</strong> – C interface for shifting an array</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"tile_201\"></a>tile()</h3>\r\n<p>The <strong>tile()</strong> function repeats an array along a dimension</p>\r\n<pre><code>a [3 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n\r\ntile(a, 2) [6 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n\r\ntile(a, 2, 2) [6 2 1 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\naf::dim4 tile_dims(1, 2, 3);\r\ntile(a, tile_dims) [3 2 3 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000</code></pre>\r\n<p>The tile function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::tile(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)</strong>  –  Tiles array along specified dimensions</li>\r\n<li><strong>array af::tile(const array &amp;in, const dim4 &amp;dims)</strong>  –  Tile an array according to a dim4 object</li>\r\n<li><strong>af_err af_tile(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong>  –  C interface for tiling an array</li>\r\n</ul>\r\n<h3><a id=\"transpose_245\"></a>transpose()</h3>\r\n<p>The <strong>transpose()</strong> function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.</p>\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     3.0000     3.0000\r\n    2.0000     1.0000     3.0000\r\n    2.0000     2.0000     1.0000\r\n\r\ntranspose(a) [3 3 1 1]\r\n    1.0000     2.0000     2.0000\r\n    3.0000     1.0000     2.0000\r\n    3.0000     3.0000     1.0000</code></pre>\r\n<p>The transpose function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::transpose(const array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>void af::transposeInPlace(array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix in-place.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose(af_array *out, af_array in, const bool conjugate)</strong> – C interface to transpose a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose_inplace(af_array in, const bool conjugate)</strong> – C interface to transpose a matrix in-place.</p>\r\n</li>\r\n</ul>\r\n<p>[array()](\\ref af::array) can be used to create a (shallow) copy of a matrix\r\nwith different dimensions.  The number of elements must remain the same as\r\nthe original array.</p>\r\n<p>\\snippet test/matrix_manipulation.cpp ex_matrix_manipulation_moddims</p>\r\n<p>The [T()](\\ref af::array::T) and [H()](\\ref af::array::H) methods can be\r\nused to form the [matrix or vector transpose](\\ref af::array::T) .</p>\r\n<p>\\snippet test/matrix_manipulation.cpp ex_matrix_manipulation_transpose</p>\r\n<h3><a id=\"Combining_reordering_functions_to_enumerate_grid_coordinates_279\"></a>Combining re-ordering functions to enumerate grid coordinates</h3>\r\n<p>By using a combination of the array restructuring functions, we can quickly code complex manipulation patterns with a few lines of code. For example, consider generating <em>(x,y)</em> coordinates for a grid where each axis goes from <em>1 to n</em>. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.</p>\r\n<pre><code><span class=\"hljs-keyword\">unsigned</span> n=<span class=\"hljs-number\">3</span>;\r\naf::<span class=\"hljs-built_in\">array</span> xy = join(<span class=\"hljs-number\">1</span>\r\n                tile(seq(<span class=\"hljs-number\">1</span>, n), n)\r\n                flat( transpose(tile(seq(<span class=\"hljs-number\">1</span>, n), <span class=\"hljs-number\">1</span>, n)) )\r\n                   );\r\nxy [<span class=\"hljs-number\">9</span> <span class=\"hljs-number\">2</span> <span class=\"hljs-number\">1</span> <span class=\"hljs-number\">1</span>]\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">1.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">2.0000</span>\r\n    <span class=\"hljs-number\">1.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">2.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n    <span class=\"hljs-number\">3.0000</span>     <span class=\"hljs-number\">3.0000</span>\r\n</code></pre>\r\n<h3><a id=\"Conclusion_298\"></a>Conclusion</h3>\r\n<p>Functions provided by arrayfire offer ease and flexibility for efficiently manipulating the structure of arrays. The provided functions can be used as building blocks to generate, shift, or prepare data to any form imaginable!</p>\r\n\r\n','Manipulating and restructuring arrays','','inherit','open','closed','','8633-revision-v1','','','2015-11-11 15:30:08','2015-11-11 15:30:08','',8633,'http://sandbox.arrayfire.com/8633-revision-v1/',0,'revision','',0),(8639,18673,'2015-11-11 15:32:11','2015-11-11 15:32:11','Now that we’ve learned how to create arrays and apply simple operations to them, lets explore how we can re-order and modify them. Arrayfire offers several functions that can easily reformat the structures of arrays.\r\n<h5><a id=\"These_functions_are_2\"></a>These functions are:</h5>\r\n<ul>\r\n	<li><strong>flat()</strong> - flatten an array to one dimension</li>\r\n	<li><strong>flip()</strong> - flip an array along a dimension</li>\r\n	<li><strong>join()</strong> - join up to 4 arrays</li>\r\n	<li><strong>moddims()</strong> - change the dimensions of an array without changing the data</li>\r\n	<li><strong>reorder()</strong> - changes the dimension order within the array</li>\r\n	<li><strong>shift()</strong> - shifts data along a dimension</li>\r\n	<li><strong>tile()</strong> - repeats an array along a dimension</li>\r\n	<li><strong>transpose()</strong> - performs a matrix transpose</li>\r\n</ul>\r\nBelow, are several examples showing the details of each function. We’ll start by defining an example matrix:\r\n<h3><a id=\"flat_15\"></a>flat()</h3>\r\n<p>The <strong>flat()</strong> function flattens an array to one dimension.</p>\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     4.0000     7.0000\r\n    2.0000     5.0000     8.0000\r\n    3.0000     6.0000     9.0000\r\n\r\nflat(a) [9 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n    6.0000\r\n    7.0000\r\n    8.0000\r\n    9.0000</code></pre>\r\n<p>The flat function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flat(const array&amp; in)</strong> – flatten an array</li>\r\n<li><strong>af_err af_flat(af_array* out, const af_array in)</strong> – C interface for flat() function</li>\r\n</ul>\r\n<h3><a id=\"flip_37\"></a>flip()</h3>\r\n<p>The <strong>flip()</strong> function flips the contents of an array along a chosen dimension.</p>\r\n<pre><code>a [5 2 1 1]\r\n    1.0000     6.0000\r\n    2.0000     7.0000\r\n    3.0000     8.0000\r\n    4.0000     9.0000\r\n    5.0000    10.0000\r\n\r\nflip(a, 0) [5 2 1 1]\r\n    5.0000    10.0000\r\n    4.0000     9.0000\r\n    3.0000     8.0000\r\n    2.0000     7.0000\r\n    1.0000     6.0000\r\n\r\nflip(a, 1) [5 2 1 1]\r\n    6.0000     1.0000\r\n    7.0000     2.0000\r\n    8.0000     3.0000\r\n    9.0000     4.0000\r\n   10.0000     5.0000</code></pre>\r\n<p>The flip function has the following overloads:</p>\r\n<ul>\r\n<li><strong>array af::flip(const array &amp;in, const unsigned dim)</strong> – flips an array along a dimension</li>\r\n<li><strong>af_err af_flip(af_array *out, const af_array in, const unsigned dim)</strong> – C interface for flip()</li>\r\n</ul>\r\n<h3><a id=\"join_65\"></a>join()</h3>\r\n<p>The <strong>join()</strong> function can join up to 4 arrays together.</p>\r\n<pre><code>a [5 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n\r\njoin(0, a, a) [10 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    4.0000\r\n    5.0000\r\n\r\njoin(1, a, a) [5 2 1 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n    4.0000     4.0000\r\n    5.0000     5.0000</code></pre>\r\n<p>The join function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second)</strong> – Joins 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third)</strong> – Joins 3 arrays along a dimension.</p>\r\n</li>\r\n<li>\r\n<p><strong>array af::join(const int dim, const array &amp;first, const array &amp;second, const array &amp;third, const array &amp;fourth)</strong> – Joins 4 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join(af_array *out, const int dim, const af_array first, const af_array second)</strong> – C interface function to join 2 arrays along a dimension</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_join_many(af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)</strong> – C interface function to join up to 10 arrays along a dimension</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"moddims_105\"></a>moddims()</h3>\r\n<p>The <strong>moddims()</strong> function changes the dimensions of an array without changing its data or order. It is important to remember that the function only modifies the <em>metadata</em> associated with the array and does not actually modify the content of the array.</p>\r\n<pre><code>a [8 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n\r\naf::dim4 new_dims(2, 4);\r\nmoddims(a, new_dims) [2 4 1 1]\r\n    1.0000     1.0000     1.0000     1.0000\r\n    2.0000     2.0000     2.0000     2.0000\r\n\r\nmoddims(a, a.elements(), 1, 1, 1) [8 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000\r\n    1.0000\r\n    2.0000</code></pre>\r\n<p>The moddims function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::moddims(const array &amp;in, const unsigned ndims, const dim_t *const dims)</strong> – mods number of dimensions to match <em>ndims</em> as specidied in the array <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim4 &amp;dims)</strong> – mods dimensions as specified by <em>dims</em></li>\r\n<li><strong>array af::moddims(const array &amp;in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)</strong> – mods dimensions of an array</li>\r\n<li><strong>af_err af_moddims(af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)</strong> – C interface to mod dimensions of an array</li>\r\n</ul>\r\n<h3><a id=\"reorder_139\"></a>reorder()</h3>\r\n<p>The <strong>reorder()</strong> function changes the order of the dimensions within the array. This actually alters the underlying data of the array.</p>\r\n<pre><code>a [2 2 3 1]\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n    1.0000     3.0000\r\n    2.0000     4.0000\r\n\r\n\r\nreorder(a, 1, 0, 2) [2 2 3 1]  //equivalent to a transpose\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n    1.0000     2.0000\r\n    3.0000     4.0000\r\n\r\n\r\nreorder(a, 2, 0, 1) [3 2 2 1]\r\n    1.0000     2.0000\r\n    1.0000     2.0000\r\n    1.0000     2.0000\r\n\r\n    3.0000     4.0000\r\n    3.0000     4.0000\r\n    3.0000     4.0000</code></pre>\r\n<p>The reorder function the following several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::reorder(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)</strong> – Reorders dimensions of an array</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_reorder(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong> – C interface for reordering function</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"shift_178\"></a>shift()</h3>\r\n<p>The <strong>shift()</strong> function shifts data in a circular buffer fashion along a chosen dimension.</p>\r\n<pre><code>a [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000\r\n    3.0000     4.0000     5.0000     1.0000     2.0000\r\n    3.0000     4.0000     5.0000     1.0000     2.0000\r\n\r\nshift(a, 0, 2 ) [3 5 1 1]\r\n    0.0000     0.0000     0.0000     0.0000     0.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n\r\nshift(a, -1, 2 ) [3 5 1 1]\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    1.0000     2.0000     3.0000     4.0000     5.0000\r\n    0.0000     0.0000     0.0000     0.0000     0.0000</code></pre>\r\n<p>The shift function has the following overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::shift(const array &amp;in, const int x, const int y=0, const int z=0, const int w=0)</strong> – Shifts array along specified dimensions</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_shift(af_array *out, const af_array in, const int x, const int y, const int z, const int w)</strong> – C interface for shifting an array</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"tile_201\"></a>tile()</h3>\r\n<p>The <strong>tile()</strong> function repeats an array along a dimension</p>\r\n<pre><code>a [3 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n\r\ntile(a, 2) [6 1 1 1]\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n    1.0000\r\n    2.0000\r\n    3.0000\r\n\r\ntile(a, 2, 2) [6 2 1 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\naf::dim4 tile_dims(1, 2, 3);\r\ntile(a, tile_dims) [3 2 3 1]\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000\r\n\r\n    1.0000     1.0000\r\n    2.0000     2.0000\r\n    3.0000     3.0000</code></pre>\r\n<p>The tile function has several overloads:</p>\r\n<ul>\r\n<li><strong>array af::tile(const array &amp;in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)</strong>  –  Tiles array along specified dimensions</li>\r\n<li><strong>array af::tile(const array &amp;in, const dim4 &amp;dims)</strong>  –  Tile an array according to a dim4 object</li>\r\n<li><strong>af_err af_tile(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)</strong>  –  C interface for tiling an array</li>\r\n</ul>\r\n<h3><a id=\"transpose_245\"></a>transpose()</h3>\r\n<p>The <strong>transpose()</strong> function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.</p>\r\n<pre><code>a [3 3 1 1]\r\n    1.0000     3.0000     3.0000\r\n    2.0000     1.0000     3.0000\r\n    2.0000     2.0000     1.0000\r\n\r\ntranspose(a) [3 3 1 1]\r\n    1.0000     2.0000     2.0000\r\n    3.0000     1.0000     2.0000\r\n    3.0000     3.0000     1.0000</code></pre>\r\n<p>The transpose function has several overloads:</p>\r\n<ul>\r\n<li>\r\n<p><strong>array af::transpose(const array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>void af::transposeInPlace(array &amp;in, const bool conjugate=false)</strong> – Transposes a matrix in-place.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose(af_array *out, af_array in, const bool conjugate)</strong> – C interface to transpose a matrix.</p>\r\n</li>\r\n<li>\r\n<p><strong>af_err af_transpose_inplace(af_array in, const bool conjugate)</strong> – C interface to transpose a matrix in-place.</p>\r\n</li>\r\n</ul>\r\n<h3><a id=\"Combining_reordering_functions_to_enumerate_grid_coordinates_279\"></a>Combining re-ordering functions to enumerate grid coordinates</h3>\r\n<p>By using a combination of the array restructuring functions, we can quickly code complex manipulation patterns with a few lines of code. For example, consider generating <em>(x,y)</em> coordinates for a grid where each axis goes from <em>1 to n</em>. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.</p>\r\n<pre><code>unsigned n=3;\r\naf::array xy = join(1\r\n                tile(seq(1, n), n)\r\n                flat( transpose(tile(seq(1, n), 1, n)) )\r\n                   );\r\nxy [9 2 1 1]\r\n    1.0000     1.0000\r\n    2.0000     1.0000\r\n    3.0000     1.0000\r\n    1.0000     2.0000\r\n    2.0000     2.0000\r\n    3.0000     2.0000\r\n    1.0000     3.0000\r\n    2.0000     3.0000\r\n    3.0000     3.0000</code></pre>\r\n<h3><a id=\"Conclusion_298\"></a>Conclusion</h3>\r\n<p>Functions provided by arrayfire offer ease and flexibility for efficiently manipulating the structure of arrays. The provided functions can be used as building blocks to generate, shift, or prepare data to any form imaginable!</p>\r\n\r\n','Manipulating and restructuring arrays','','inherit','open','closed','','8633-revision-v1','','','2015-11-11 15:32:11','2015-11-11 15:32:11','',8633,'http://sandbox.arrayfire.com/8633-revision-v1/',0,'revision','',0),(8640,18673,'2015-12-03 22:42:56','0000-00-00 00:00:00','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp;&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>,&nbsp;&nbsp;&nbsp;&nbsp; where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X\'X) * X\'                                \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code>X = constant(1, NSAMPLES, N_order, f32);\r\n X.col(1) *= particles.col(0);\r\n for(int i=2; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-1) * particles.col(0); //replace each column with one order higher column\r\n// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U;\r\ncholesky(U, matmul(X.T(), X), true); //cholesky on X\'X, true parameter for upper triangular portion\r\narray z = solve(U.T(), matmul(X.T(), particles.col(1)), AF_MAT_LOWER); //solve and specify the coefficients are lower triangular for optimized solution method\r\nb = solve(U, z, AF_MAT_UPPER); //solve and specify the coefficients are upper triangular</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found <a href=\"https://github.com/syurkevi/leastsquares_arrayfire_example\">here.</a>\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','draft','open','closed','','','','','2015-12-03 22:42:56','2015-12-03 22:42:56','',0,'http://sandbox.arrayfire.com/?p=8640',0,'post','',0),(8641,18673,'2015-11-12 22:23:31','2015-11-12 22:23:31','Untitled Document.md\r\n<h1><a id=\"Simple_Linear_Least_Squares_Regression_with_Arrayfire_0\"></a>Simple Linear Least Squares Regression with Arrayfire</h1>\r\nToday, we willl be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelised gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) datapoints of the form\r\n\r\n<strong>{y<sub>i</sub>, x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\n\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms:\r\n<strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>\r\n, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code><span class=\"hljs-built_in\">array</span> particles = randu(NSAMPLES, <span class=\"hljs-number\">2</span>); <span class=\"hljs-comment\">//generate (NSAMPLE x 2) random uniform matrix</span>\r\n<span class=\"hljs-comment\">//scale [0,1] to [0, WIDTH] and [0, HEIGHT]</span>\r\nparticles.col(<span class=\"hljs-number\">0</span>) *= WIDTH;\r\nparticles.col(<span class=\"hljs-number\">1</span>) *= HEIGHT;\r\n</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code><span class=\"hljs-built_in\">array</span> X = constant( <span class=\"hljs-number\">1</span>, NSAMPLES, <span class=\"hljs-number\">2</span>, f32);\r\nX.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">// X [NSAMPLES 2] = [ 1  xvals ]</span>\r\n</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul<span class=\"hljs-list\">(  <span class=\"hljs-keyword\">matmul</span><span class=\"hljs-list\">(<span class=\"hljs-keyword\">inverse</span><span class=\"hljs-list\">(<span class=\"hljs-keyword\">matmul</span><span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>)</span>, X.T<span class=\"hljs-list\">()</span>)</span>, // <span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T*X)</span> <span class=\"hljs-variable\">* X.T \r\n                   particles.col(1)                          //   *</span> y\r\n                )</span><span class=\"hljs-comment\">;</span>\r\n</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image =<span class=\"hljs-function\"> constant(</span>0, HEIGHT, WIDTH, f32<span class=\"hljs-function\">)</span>; //declare a black image to match our window<span class=\"hljs-instruction\">\r\narray </span>ids(NSAMP<span class=\"hljs-class\">LES, u32);</span> //indexes specifying where in the image we should draw white\r\nids =<span class=\"hljs-function\"> (</span>particles.col(0<span class=\"hljs-function\">)</span>.as(u32<span class=\"hljs-function\">)</span> *<span class=\"hljs-function\"> (</span>HEIGHT<span class=\"hljs-function\">)</span><span class=\"hljs-function\">)</span> +<span class=\"hljs-function\"> particles.col(</span>1<span class=\"hljs-function\">)</span>.as(u32<span class=\"hljs-function\">)</span>;\r\nimage(ids<span class=\"hljs-function\">)</span> = 1; //fill the specified indices with white\r\n<span class=\"hljs-instruction\">\r\narray </span>mask_point =<span class=\"hljs-function\"> array(</span>5, 5, point_kernel<span class=\"hljs-function\">)</span>;\r\nimage =<span class=\"hljs-function\"> dilate(</span>image, mask_point<span class=\"hljs-function\">)</span>; //dilate operation with point_kernel to prettify points\r\n</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code><span class=\"hljs-keyword\">float</span> *<span class=\"hljs-keyword\">params</span> = b.host&lt;<span class=\"hljs-keyword\">float</span>&gt;(); <span class=\"hljs-comment\">//copy params from device to host array</span>\r\narray yplot = range(dim4(WIDTH)) * <span class=\"hljs-keyword\">params</span>[<span class=\"hljs-number\">1</span>] + <span class=\"hljs-keyword\">params</span>[<span class=\"hljs-number\">0</span>]; <span class=\"hljs-comment\">//y = b1*x + b0</span>\r\ndelete [] <span class=\"hljs-keyword\">params</span>;  <span class=\"hljs-comment\">//implicitly allocated params must be freed</span>\r\n\r\nids = (range(dim4(WIDTH)).<span class=\"hljs-keyword\">as</span>(u32) * (HEIGHT)) + yplot.<span class=\"hljs-keyword\">as</span>(u32); <span class=\"hljs-comment\">//computes the indices in our image that the line passes through</span>\r\nids = ids(yplot &gt; <span class=\"hljs-number\">0</span> &amp;&amp; yplot &lt; HEIGHT); <span class=\"hljs-comment\">//filters the ids where our y-values are out of bounds</span>\r\n</code></pre>\r\nAnd voila!\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.\r\n\r\n&nbsp;','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:23:31','2015-11-12 22:23:31','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8642,18673,'2015-11-12 22:29:08','2015-11-12 22:29:08','','Screenshot from 2015-11-12 16_56_51','','inherit','open','closed','','screenshot-from-2015-11-12-16_56_51','','','2015-11-12 22:29:08','2015-11-12 22:29:08','',8640,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_51.png',0,'attachment','image/png',0),(8643,18673,'2015-11-12 22:29:11','2015-11-12 22:29:11','','Screenshot from 2015-11-12 16_59_25','','inherit','open','closed','','screenshot-from-2015-11-12-16_59_25','','','2015-11-12 22:29:11','2015-11-12 22:29:11','',8640,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_25.png',0,'attachment','image/png',0),(8644,18673,'2015-11-12 22:33:53','2015-11-12 22:33:53','','Least square linear regression','','inherit','open','closed','','screenshot-from-2015-11-12-16_56_51-2','','','2015-11-12 22:34:14','2015-11-12 22:34:14','',8640,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png',0,'attachment','image/png',0),(8645,18673,'2015-11-12 22:33:54','2015-11-12 22:33:54','','Screenshot from 2015-11-12 16_59_25','','inherit','open','closed','','screenshot-from-2015-11-12-16_59_25-2','','','2015-11-12 22:33:54','2015-11-12 22:33:54','',8640,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251.png',0,'attachment','image/png',0),(8646,18673,'2015-11-12 22:35:09','2015-11-12 22:35:09','Simple Linear Least Squares Regression with Arrayfire\r\n\r\nToday, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form\r\n\r\n<strong>{y<sub>i</sub>, x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\n\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms:\r\n<strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>\r\n, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) *= particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X.T*X) * X.T \r\n                   particles.col(1)                          //   * y\r\n                );</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:35:09','2015-11-12 22:35:09','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8647,18673,'2015-11-12 22:35:23','2015-11-12 22:35:23','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form\r\n\r\n<strong>{y<sub>i</sub>, x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\n\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms:\r\n<strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>\r\n, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) *= particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X.T*X) * X.T \r\n                   particles.col(1)                          //   * y\r\n                );</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:35:23','2015-11-12 22:35:23','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8648,18673,'2015-11-12 22:44:04','2015-11-12 22:44:04','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>, x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), \r\n                                                          // (X.T*X) * X.T \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:44:04','2015-11-12 22:44:04','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8649,18673,'2015-11-12 22:44:58','2015-11-12 22:44:58','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&amp;nbsp&amp;nbsp x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), \r\n                                                          // (X.T*X) * X.T \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:44:58','2015-11-12 22:44:58','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8650,18673,'2015-11-12 22:45:49','2015-11-12 22:45:49','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>, where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), \r\n                                                          // (X.T*X) * X.T \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:45:49','2015-11-12 22:45:49','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8651,18673,'2015-11-12 22:46:30','2015-11-12 22:46:30','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp;&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>,&nbsp;&nbsp;&nbsp;&nbsp; where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), \r\n                                                          // (X.T*X) * X.T \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code> X = constant(<span class=\"hljs-number\">1</span>, NSAMPLES, N_order, f32);\r\n X.col(<span class=\"hljs-number\">1</span>) *= particles.col(<span class=\"hljs-number\">0</span>);\r\n <span class=\"hljs-keyword\">for</span>(<span class=\"hljs-keyword\">int</span> i=<span class=\"hljs-number\">2</span>; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-<span class=\"hljs-number\">1</span>) * particles.col(<span class=\"hljs-number\">0</span>); <span class=\"hljs-comment\">//replace each column with one order higher column</span>\r\n<span class=\"hljs-comment\">// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</span>\r\n</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U<span class=\"hljs-comment\">;</span>\r\ncholesky<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, X)</span>, true)</span><span class=\"hljs-comment\">; //cholesky on X\'X, true parameter for upper triangular portion</span>\r\narray z = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>.T<span class=\"hljs-list\">()</span>, matmul<span class=\"hljs-list\">(<span class=\"hljs-keyword\">X</span>.T<span class=\"hljs-list\">()</span>, particles.col<span class=\"hljs-list\">(<span class=\"hljs-number\">1</span>)</span>)</span>, AF_MAT_LOWER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are lower triangular for optimized solution method</span>\r\nb = solve<span class=\"hljs-list\">(<span class=\"hljs-keyword\">U</span>, z, AF_MAT_UPPER)</span><span class=\"hljs-comment\">; //solve and specify the coefficients are upper triangular</span>\r\n</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:46:30','2015-11-12 22:46:30','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8652,18673,'2015-11-12 22:57:50','2015-11-12 22:57:50','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp;&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>,&nbsp;&nbsp;&nbsp;&nbsp; where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X\'X) * X\'                                \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code>X = constant(1, NSAMPLES, N_order, f32);\r\n X.col(1) *= particles.col(0);\r\n for(int i=2; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-1) * particles.col(0); //replace each column with one order higher column\r\n// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U;\r\ncholesky(U, matmul(X.T(), X), true); //cholesky on X\'X, true parameter for upper triangular portion\r\narray z = solve(U.T(), matmul(X.T(), particles.col(1)), AF_MAT_LOWER); //solve and specify the coefficients are lower triangular for optimized solution method\r\nb = solve(U, z, AF_MAT_UPPER); //solve and specify the coefficients are upper triangular</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 22:57:50','2015-11-12 22:57:50','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8654,18673,'2015-11-12 23:15:10','2015-11-12 23:15:10','Today, we will be looking at solving a simple linear least squares regression problem with Arrayfire. Least squares regression is a commonly used form of linear regression. The often large sample sizes and underlying matrix operations used for fitting Linear Least Squares makes it an excellent candidate for a parallelized gpu. The specific problem we will be examining today is the classic polynomial fit to a scattered collection of points.\r\n<h3><a id=\"Mathematical_Background_4\"></a>Mathematical Background</h3>\r\nLinear regression methods model relationships between a dependent variable (<strong>y</strong>) and one or more independent variables (<strong>X</strong>). Linear regression explores the conditional probability ( <strong>y</strong> | <strong>X</strong> ) Data are modeled using <em>linear</em> predictor functions. Given this linearity assumption between the dependent and independent variables, and (n) data points of the form:\r\n<strong>{y<sub>i</sub>,&nbsp;&nbsp;&nbsp;&nbsp; x<sub>i1</sub>, … , x<sub>ip</sub>}</strong> ,\r\nwe can construct a model of the form:\r\n\r\n<strong>y<sub>i</sub> = b<sub>1</sub>x<sub>i1</sub> + … + b<sub>p</sub>x<sub>ip</sub> + <em>e</em><sub>i</sub></strong>,&nbsp;&nbsp;&nbsp;&nbsp; where <strong>i = 1, …, n</strong>.\r\n\r\nor, if we stack each point’s linear model atop each other, in vector form:\r\n\r\n<strong>y = Xb + <em>e</em></strong>    where,\r\n\r\n<strong>y</strong> - vector of dependent variables\r\n<strong>X</strong> - “Design Matrix” of size <em>(n x p)</em> . This matrix contains the independent variables.\r\n<strong>b</strong> - parameter vector the regression will be fitting\r\n<strong>e</strong> - error vector/noise\r\n\r\nThe goal of least squares linear regression is to find a parameter vector <strong>b</strong> such that the square of the error is minimized:\r\n\r\n<strong>b = argmin<sub>b</sub> S( b ) = argmin<sub>b</sub>|| e || <sup>2</sup> = argmin<sub>b</sub> || y - Xb || <sup>2</sup></strong>,\r\n\r\nwhere <strong>S( b )</strong> – cost function.\r\n\r\nSolving the minimization can be done through various gradient descent methods which iteratively work to set the gradient vector of the cost function to <strong>0</strong>. The minimized gradient of the cost function can also be found analytically. The resulting equations are called the normal equations and can be written in vector form as:\r\n\r\n<strong>(X<sup>T</sup>X) b = X<sup>T</sup>y</strong>\r\n\r\nAfter a quick re-arrangement, we can algebraically solve for our parameter vector:\r\n\r\n<strong>b = (X<sup>T</sup>X)<sup>-1</sup> X<sup>T</sup>y</strong>\r\n\r\nOn first glance, our specific problem of fitting an n-order polynomial(for example n = 5) might not seem like a linear problem since we have quadratic, cubic, and higher terms: <strong>y = x<sup>5</sup> + x<sup>4</sup> + x<sup>3</sup> + x<sup>2</sup> + x<sup>1</sup> + x<sup>0</sup></strong>, however we are actually fitting the parameter vector <em>b</em> and our equation is of the linear combination form:\r\n<strong>y = b<sub>1</sub>x<sup>5</sup> + b<sub>2</sub>x<sup>4</sup> + b<sub>3</sub>x<sup>3</sup> + b<sub>4</sub>x<sup>2</sup> + b<sub>5</sub>x<sup>1</sup> + b<sub>6</sub>x<sup>0</sup></strong>\r\n<h3><a id=\"Coding_with_Arrayfire_32\"></a>Coding with Arrayfire</h3>\r\nThe set of points to be fitted will be located within a window of size (WIDTH, HEIGHT). First, generate a set of points within the window:\r\n<pre><code>array particles = randu(NSAMPLES, 2); //generate (NSAMPLE x 2) random uniform matrix\r\n//scale [0,1] to [0, WIDTH] and [0, HEIGHT]\r\nparticles.col(0) *= WIDTH;\r\nparticles.col(1) *= HEIGHT;</code></pre>\r\nThen, form our regressors matrix <strong>( X )</strong>:\r\n<pre><code>array X = constant( 1, NSAMPLES, 2, f32);\r\nX.col(1) = particles.col(0); // X [NSAMPLES 2] = [ 1  xvals ]</code></pre>\r\nWith the dependent and independent variables prepared, evaluate the algebraic solution for the parameter vector <strong>b</strong>:\r\n<pre><code>array b = matmul(  matmul(inverse(matmul(X.T(), X)), X.T()), // (X\'X) * X\'                                \r\n                   particles.col(1) );                    //   * y</code></pre>\r\nNow that we have found <strong>b</strong>, we have a complete linear model that predicts <strong>( y | X )</strong>. It would be nice if we could see this linear model, so we will attempt to draw a simple grayscale visualization. First, set up an “image” matrix and visualize our original dataset:\r\n<pre><code>array image = constant(0, HEIGHT, WIDTH, f32); //declare a black image to match our window\r\narray ids(NSAMPLES, u32); //indexes specifying where in the image we should draw white\r\nids = (particles.col(0).as(u32) * (HEIGHT)) + particles.col(1).as(u32);\r\nimage(ids) = 1; //fill the specified indices with white\r\n\r\narray mask_point = array(5, 5, point_kernel);\r\nimage = dilate(image, mask_point); //dilate operation with point_kernel to prettify points</code></pre>\r\nThen plot the fitted line on our “image”:\r\n<pre><code>float *params = b.host(); //copy params from device to host array\r\narray yplot = range(dim4(WIDTH)) * params[1] + params[0]; //y = b1*x + b0\r\ndelete [] params;  //implicitly allocated params must be freed\r\n\r\nids = (range(dim4(WIDTH)).as(u32) * (HEIGHT)) + yplot.as(u32); //computes the indices in our image that the line passes through\r\nids = ids(yplot &gt; 0 &amp;&amp; yplot &lt; HEIGHT); //filters the ids where our y-values are out of bounds</code></pre>\r\nAnd voila!\r\n<h3> <a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511.png\"><img class=\" size-medium wp-image-8644 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_56_511-300x150.png\" alt=\"Least square linear regression\" width=\"300\" height=\"150\" /></a></h3>\r\n<h3><a id=\"Coding_for_higher_order_polynomials_72\"></a>Coding for higher order polynomials</h3>\r\nIdeally, we would be able to fit any n-th order polynomial to our data, so first, prepare our design matrix to follow the higher order terms:\r\n<pre><code>X = constant(1, NSAMPLES, N_order, f32);\r\n X.col(1) *= particles.col(0);\r\n for(int i=2; i&lt;N_order; ++i)\r\n    X.col(i) = X.col(i-1) * particles.col(0); //replace each column with one order higher column\r\n// X [NSAMPLES N_order] = [ 1 x x^2 x^3 ... x^N_order]</code></pre>\r\nOur equations remain the same <strong>( (X<sup>T</sup>X) b = X<sup>T</sup>y )</strong>, and while the identical algebraic solution for <strong>b</strong> would work it is quite inefficient to find the inverse of a (now) large normal equations Gramian matrix <strong>( X<sup>T</sup>X )</strong>. Instead, since the Gramian matrix has the nice property of being a positive semi-definite matrix, we can substitute it with the result of a Cholesky decomposition. The equation slightly changes <strong>( U<sup>T</sup>U b = X<sup>T</sup>y )</strong> and the procedure is as follows:\r\n<ul>\r\n	<li>Find the upper triangular matrix <strong>( U )</strong> from the Cholesky decomposition of <strong>( X<sup>T</sup>X)</strong></li>\r\n	<li>Solve for vector z in <strong>U<sup>T</sup>z = X<sup>T</sup>y</strong></li>\r\n	<li>Finally, solve for the parameter vector <strong>b</strong> in <strong>Ub = z</strong></li>\r\n</ul>\r\nSuprisingly, Arrayfire has convenient functions for each of these steps.\r\n<pre><code>array U;\r\ncholesky(U, matmul(X.T(), X), true); //cholesky on X\'X, true parameter for upper triangular portion\r\narray z = solve(U.T(), matmul(X.T(), particles.col(1)), AF_MAT_LOWER); //solve and specify the coefficients are lower triangular for optimized solution method\r\nb = solve(U, z, AF_MAT_UPPER); //solve and specify the coefficients are upper triangular</code></pre>\r\nAnd our result:\r\n\r\n<img class=\" size-medium wp-image-8645 aligncenter\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/Screenshot-from-2015-11-12-16_59_251-300x150.png\" alt=\"Screenshot from 2015-11-12 16_59_25\" width=\"300\" height=\"150\" />\r\n\r\nThe complete source code for this project can be found here:\r\nhttps://github.com/syurkevi/leastsquares_arrayfire_example\r\n<h3><a id=\"Conclusion_98\"></a>Conclusion</h3>\r\nWe have implemented a least squares linear regression with Arrayfire and also visualized its results. Arrayfire provides many convenient functions which allowed us to choose the most robust method of solving our problem without sacrificing convenience and ease of coding.','Linear Least Squares Regression with Arrayfire','','inherit','open','closed','','8640-revision-v1','','','2015-11-12 23:15:10','2015-11-12 23:15:10','',8640,'http://sandbox.arrayfire.com/8640-revision-v1/',0,'revision','',0),(8655,11,'2015-11-13 17:38:04','2015-11-13 17:38:04','[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\"]\r\n[custom_headline type=\"left\" level=\"h2\"]\r\nArrayFire Installers\r\n[/custom_headline]\r\n[custom_headline type=\"left\" level=\"h5\"]\r\nEach download contains both CUDA and OpenCL files.\r\n[/custom_headline]\r\n[gap size=\"4%\"]\r\n\r\n[column type=\"one-fourth\"][button  block=\"true\" onclick=\"&lt;!-- Google Code for ArrayFire Download (Windows) Conversion Page\r\nIn your html page, add the snippet and call\r\ngoog_report_conversion when someone clicks on the\r\nchosen link or button. --&gt;\r\n&lt;script type=\"text/javascript\"&gt;\r\n/* &lt;!&amp;#91;CDATA&amp;#91; */\r\ngoog_snippet_vars = function() {\r\nvar w = window;\r\nw.google_conversion_id = 1021026651;\r\nw.google_conversion_label = \"18VJCJjPql4Q28Lu5gM\";\r\nw.google_remarketing_only = false;\r\n}\r\n// DO NOT CHANGE THE CODE BELOW.\r\ngoog_report_conversion = function(url) {\r\ngoog_snippet_vars();\r\nwindow.google_conversion_format = \"3\";\r\nwindow.google_is_call = true;\r\nvar opt = new Object();\r\nopt.onload_callback = function() {\r\nif (typeof(url) != \'undefined\') {\r\nwindow.location = url;\r\n}\r\n}\r\nvar conv_handler = window&amp;#91;\'google_trackConversion\'&amp;#93;;\r\nif (typeof(conv_handler) == \'function\') {\r\nconv_handler(opt);\r\n}\r\n}\r\n/* &amp;#93;&amp;#93;&gt; */\r\n&lt;/script&gt;\r\n&lt;script type=\"text/javascript\"\r\nsrc=\"//www.googleadservices.com/pagead/conversion_async.js\"&gt;\r\n&lt;/script&gt;\" class=\"center-text\" type=\"flat\" shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/windows-installer\" size=\"regular\" ]Windows, v3.2.0\r\n(64-bit)[/button][/column] [column type=\"one-fourth\"][button block=\"true\" type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/linux-x86_64-installer\" size=\"regular\" ]Linux, v3.2.0\r\n(64-bit)[/button][/column][column type=\"one-fourth\"][button  block=\"true\" type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/osx-installer\" size=\"regular\" ]Mac OSX, v3.2.0\r\n(64-bit)[/button][/column] [column type=\"one-fourth\" last=\"true\"][button block=\"true\"  type=\"flat\"  shape=\"rounded\" href=\"http://go.sandbox.arrayfire.com/linux-armv7l-installer\" size=\"regular\" ]Tegra K1 v3.2.0\r\n(32-bit)[/button][/column][gap size=\"9%\"]\r\n\r\nCheck out our GitHub repository to <a href=\"https://github.com/arrayfire/arrayfire\">build from the source</a>.\r\n\r\nLooking for an older installer? <a href=\"http://sandbox.arrayfire.com/installer_archive\">Try here</a>.[/content_band]\r\n<p style=\"text-align: left;\">[content_band inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"10px\" padding_bottom=\"40px\" bg_color=\"#f1f1f1\"][column type=\"one-half\"][gap size=\"8%\"]<img class=\"aligncenter wp-image-5156\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/02/mobile_Exported1-e1395437261846.png\" alt=\"mobile_Exported\" width=\"233\" height=\"311\" />[/column][column type=\"one-half\" last=\"true\"]\r\n[custom_headline type=\"left\" level=\"h2\"]\r\nGreat. What now?\r\n[/custom_headline]</p>\r\n<p style=\"text-align: left;\">[gap size=\"5%\"]</p>\r\n<p style=\"text-align: left;\">Welcome to ArrayFire! You\'ve got an awesome library there—learn more about its features and functions on <a href=\"http://www.sandbox.arrayfire.com/docs/index.htm\">our documentation</a>.</p>\r\n<p style=\"text-align: left;\">In addition to our <a href=\"https://groups.google.com/forum/#!forum/arrayfire-users\">ArrayFire user group</a> and <a href=\"http://sandbox.arrayfire.com/blog/\">our blog</a>, we offer a plethora of <a href=\"http://sandbox.arrayfire.com/support/\">support options</a> to fit your needs.</p>\r\n<p style=\"text-align: left;\">Got a job that needs closer attention? Hire us! Our engineers are acceleration wizards. Check out our <a href=\"http://sandbox.arrayfire.com/consulting/\">consulting offerings</a>, or set up a free <a href=\"http://meetme.so/arrayfire\">technical consultation</a> with us today![/column]</p>\r\n<p style=\"text-align: left;\">[/content_band]</p>\r\n<p style=\"text-align: center;\"></p>','Download','','inherit','open','closed','','5931-revision-v1','','','2015-11-13 17:38:04','2015-11-13 17:38:04','',5931,'http://sandbox.arrayfire.com/5931-revision-v1/',0,'revision','',0),(8657,17729,'2015-11-13 20:41:47','2015-11-13 20:41:47','[vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][custom_headline type=\"left\" level=\"h3\"]About[/custom_headline][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/dj-Flame.png\"][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][line][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Email[/custom_headline][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Phone[/custom_headline][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Headquarters[/custom_headline][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][custom_headline type=\"left\" level=\"h3\"]Careers[/custom_headline][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/little-boba-fett.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Software Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities:</strong> Develop in C/C++, Fortran, CUDA, and OpenCL. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications</strong>: A background in any of high-performance computing, operating systems, or compilers. Several years of C/C++ and at least one year of CUDA or similar technology. Familiarity with Fortran is a plus. Undergraduate or graduate work in CS or related field. [custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Software Engineer - Atlanta, GA[/custom_headline][/promo][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/uncle-sam.png\" alt=\"Alt Text\"] [custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Application Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Work closely with customers to develop software solutions using our products. Develop technical marketing materials including demos, webinars, tutorials, etc. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications:</strong> Undergraduate or graduate work in CS or related field. Strong programming skills in C/C++. Excellent communication skills.[custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Application Engineer - Atlanta, GA[/custom_headline][/promo][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/i-see-pride-i-see-power.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Web/Dev Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Develop PHP/MySQL backend infrastructure with basic HTML/CSS/JavaScript frontend work. Developing lightweight webapps for system monitoring. Maintaining Wordpress and SalesForce integration. Maintaining server/cluster infrastructure.\r\n\r\n<strong>Qualifications:</strong> Strong PHP and MySQL experience. Very comfortable at a shell prompt. Proficient in HTML, CSS, and JavaScript. Familiarity with Wordpress or SalesForce is a plus.[custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Web/Dev Engineer - Atlanta, GA[/custom_headline][/promo][vc_row][vc_column width=\"1/1\"][/vc_column][/vc_row][vc_row][vc_column width=\"1/1\"][text_output]<h5>Current full time opportunities</h5>\n\n<h6>TITLE:</h6> Software Systems Engineers\n\n<h6>Work Start Date:</h6> Immediate\n\n<h6>JOB DUTIES:</h6>\n\nDevelop in C/C++, CUDA/ OpenCL: Focus development efforts in the C and C++ programming languages, using CUDA (Compute Unified Device Architecture) or OpenCL (Open Computing Language) API\'s to allow high performance computation on GPUs (Graphical Processing Units) of many different vendors; Develop new ArrayFire features and functionality based on market and customer needs; Optimize, analyze and profile code to ensure maximum use of hardware capabilities, including optimal usage of GPU\'s memory bandwidth and occupancy; Enhance optimization of the ArrayFire software library; Maintain ArrayFire software library interoperability with various operating systems and hardware architectures; Assist in ArrayFire development roadmap to ensure new releases are compatible with the latest hardware and software available on the market; Maintain ArrayFire documentation; Ensure quality assurance of ArrayFire software library; Develop effective QA testing and debugging procedures, ensuring ArrayFire will maintain a robust and high level of functionality; Develop test cases that will verify and ensure ArrayFire software for correctness and performance, including during boundary situations; Participation in core-product development; Development of software and content that accompany the core product to enrich user-experience; Development and maintenance of in-house software tools and processes to ensure a smooth development cycle and efficient quality control; Handle customer projects that require code-optimization using the product; Serve as technical consultant to customers and debug/resolve issues with the product.\n\n<h6>REQUIREMENTS:</h6>\n\nApplicants need to have a Master’s degree (or foreign equiv.) in Computer Science or any IT related field, or any Engineering field. Knowledge of the following: C, C+, CUDA/OpenCL/ Multicore/ Parallel Programming, Architecture, GPUs/ Accelerators, Linux, P-Threads, SimD, Linear Algebra, Python.\n\n\nMinimum Requirements Apply To The Positions Listed Above. Please Refer To This Advertisement. No Phone Calls Please. Equal Opportunity Employer.\n\n<h6>Please Mail Your Resume To:</h6>\n \nHR Manager\nAccelerEyes, LLC\n3405 Piedmont Road NE, Suite 100\nAtlanta, GA 30305[/text_output][/vc_column][/vc_row]','Company','','inherit','open','closed','','329-revision-v1','','','2015-11-13 20:41:47','2015-11-13 20:41:47','',329,'http://sandbox.arrayfire.com/329-revision-v1/',0,'revision','',0),(8658,17729,'2015-11-13 20:43:33','2015-11-13 20:43:33','[content_band inner_container=\"true\" no_margin=\"true\" border=\"bottom\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"] [custom_headline type=\"left\" level=\"h3\" ]About[/custom_headline]ArrayFire is the software shop for CUDA and OpenCL. Since 2007, ArrayFire has offered the most productive solutions for accelerating code using GPUs. Today, ArrayFire delivers products which are used to accelerate C, C++, and Fortran codes on CUDA GPUs and OpenCL devices. ArrayFire has thousands of customers. These customers come from a wide range of industries, including defense and intelligence, life science, oil and gas, finance, manufacturing, media, and others.\r\n\r\nArrayFire has had success accelerating numerous application types, including math and numerical algorithms, image processing, signal processing, statistics, optimization, and more. Many ArrayFire customers are realizing 100X speed-up with much less effort than is typically required to accelerate code.[/column][column type=\"one-half\" last=\"true\" fade=\"true\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/dj-Flame.png\"] [/column]\r\n<div id=\"contact\"></div>\r\n[line][column type=\"one-third\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Email[/custom_headline]\r\n<p style=\"text-align: center;\">Sales: sales@arrayfire.com\r\nSupport: support@arrayfire.com\r\nCareers: jobs@arrayfire.com[/column]</p>\r\n[column type=\"one-third\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Phone[/custom_headline]\r\n<p style=\"text-align: center;\">Sales: +1 (800) 570-1941 x 1\r\nTechnical Support: +1 (800) 570-1941 x 2 [/column]</p>\r\n[column type=\"one-third\" last=\"true\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Headquarters[/custom_headline]\r\n<p style=\"text-align: center;\">3405 Piedmont Rd NE STE 100\r\nAtlanta, GA 30305[/column] [/content_band]</p>\r\n[content_band bg_color=\"#f2f2f2\" inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\" ][column type=\"one-half\"][custom_headline type=\"left\" level=\"h3\" ]Careers[/custom_headline]As a global leader in GPU computing software, our business opportunities are always expanding. We are constantly searching for talented, qualified individuals to join the ArrayFire team. ArrayFire is committed to providing employees with the opportunity to grow and learn, the freedom to express ideas and contribute to new developments, and the motivation to succeed. To start the application process, simply email us your resume and let us know which position(s) you\'re interested in.[/column][column type=\"one-half\" last=\"true\"].[/column]\r\n\r\n&nbsp;\r\n\r\n[column type=\"one-third\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/little-boba-fett.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Software Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities:</strong> Develop in C/C++, Fortran, CUDA, and OpenCL. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications</strong>: A background in any of high-performance computing, operating systems, or compilers. Several years of C/C++ and at least one year of CUDA or similar technology. Familiarity with Fortran is a plus. Undergraduate or graduate work in CS or related field. [/promo][/column]\r\n\r\n[column type=\"one-third\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/uncle-sam.png\" alt=\"Alt Text\"] [custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Application Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Work closely with customers to develop software solutions using our products. Develop technical marketing materials including demos, webinars, tutorials, etc. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications:</strong> Undergraduate or graduate work in CS or related field. Strong programming skills in C/C++. Excellent communication skills.[/promo][/column]\r\n\r\n[column type=\"one-third\" last=\"true\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/i-see-pride-i-see-power.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Web/Dev Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Develop PHP/MySQL backend infrastructure with basic HTML/CSS/JavaScript frontend work. Developing lightweight webapps for system monitoring. Maintaining Wordpress and SalesForce integration. Maintaining server/cluster infrastructure.\r\n\r\n<strong>Qualifications:</strong> Strong PHP and MySQL experience. Very comfortable at a shell prompt. Proficient in HTML, CSS, and JavaScript. Familiarity with Wordpress or SalesForce is a plus.[/promo][/column][/content_band]','Company','','inherit','open','closed','','329-revision-v1','','','2015-11-13 20:43:33','2015-11-13 20:43:33','',329,'http://sandbox.arrayfire.com/329-revision-v1/',0,'revision','',0),(8661,17729,'2015-11-13 21:16:04','2015-11-13 21:16:04','[content_band inner_container=\"true\" no_margin=\"true\" border=\"bottom\" padding_top=\"40px\" padding_bottom=\"40px\"][column type=\"one-half\"] [custom_headline type=\"left\" level=\"h3\" ]About[/custom_headline]ArrayFire is the software shop for CUDA and OpenCL. Since 2007, ArrayFire has offered the most productive solutions for accelerating code using GPUs. Today, ArrayFire delivers products which are used to accelerate C, C++, and Fortran codes on CUDA GPUs and OpenCL devices. ArrayFire has thousands of customers. These customers come from a wide range of industries, including defense and intelligence, life science, oil and gas, finance, manufacturing, media, and others.\r\n\r\nArrayFire has had success accelerating numerous application types, including math and numerical algorithms, image processing, signal processing, statistics, optimization, and more. Many ArrayFire customers are realizing 100X speed-up with much less effort than is typically required to accelerate code.[/column][column type=\"one-half\" last=\"true\" fade=\"true\"][image src=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/dj-Flame.png\"] [/column]\r\n<div id=\"contact\"></div>\r\n[line][column type=\"one-third\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Email[/custom_headline]\r\n<p style=\"text-align: center;\">Sales: sales@arrayfire.com\r\nSupport: support@arrayfire.com\r\nCareers: jobs@arrayfire.com[/column]</p>\r\n[column type=\"one-third\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Phone[/custom_headline]\r\n<p style=\"text-align: center;\">Sales: +1 (800) 570-1941 x 1\r\nTechnical Support: +1 (800) 570-1941 x 2 [/column]</p>\r\n[column type=\"one-third\" last=\"true\"][custom_headline type=\"center\" level=\"h5\" accent=\"false\"]Headquarters[/custom_headline]\r\n<p style=\"text-align: center;\">3405 Piedmont Rd NE STE 100\r\nAtlanta, GA 30305[/column] [/content_band]</p>\r\n[content_band bg_color=\"#f2f2f2\" inner_container=\"true\" no_margin=\"true\" border=\"none\" padding_top=\"40px\" padding_bottom=\"40px\" ][column type=\"full\"][custom_headline type=\"left\" level=\"h3\" ]Careers[/custom_headline]As a global leader in GPU computing software, our business opportunities are always expanding. We are constantly searching for talented, qualified individuals to join the ArrayFire team. ArrayFire is committed to providing employees with the opportunity to grow and learn, the freedom to express ideas and contribute to new developments, and the motivation to succeed. To start the application process, simply email us your resume and let us know which position(s) you\'re interested in.[/column]\r\n\r\n[line][column type=\"one-third\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/little-boba-fett.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Software Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities:</strong> Develop in C/C++, Fortran, CUDA, and OpenCL. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications</strong>: A background in any of high-performance computing, operating systems, or compilers. Several years of C/C++ and at least one year of CUDA or similar technology. Familiarity with Fortran is a plus. Undergraduate or graduate work in CS or related field. [/promo][/column]\r\n\r\n[column type=\"one-third\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/uncle-sam.png\" alt=\"Alt Text\"] [custom_headline type=\"left\" level=\"h5\"  class=\"mtn\"]Application Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Work closely with customers to develop software solutions using our products. Develop technical marketing materials including demos, webinars, tutorials, etc. Respond to forum posts and customer support tickets.\r\n\r\n<strong>Qualifications:</strong> Undergraduate or graduate work in CS or related field. Strong programming skills in C/C++. Excellent communication skills.[/promo][/column]\r\n\r\n[column type=\"one-third\" last=\"true\"][promo image=\"http://sandbox.arrayfire.com/wp-content/uploads/2014/01/i-see-pride-i-see-power.png\" alt=\"Alt Text\"][custom_headline type=\"left\" level=\"h5\" class=\"mtn\"]Web/Dev Engineer - Atlanta, GA[/custom_headline]\r\n\r\n<strong>Responsibilities: </strong>Develop PHP/MySQL backend infrastructure with basic HTML/CSS/JavaScript frontend work. Developing lightweight webapps for system monitoring. Maintaining Wordpress and SalesForce integration. Maintaining server/cluster infrastructure.\r\n\r\n<strong>Qualifications:</strong> Strong PHP and MySQL experience. Very comfortable at a shell prompt. Proficient in HTML, CSS, and JavaScript. Familiarity with Wordpress or SalesForce is a plus.[/promo][/column]\r\n\r\n[line]\r\n\r\n[column type=\"full\"][custom_headline type=\"left\" level=\"h3\" ]Current full time opportunities[/custom_headline]\r\n<p class=\"western\" lang=\"en-US\" align=\"left\"><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\"><strong>TITLE:</strong> </span></span>Software Systems Engineers</p>\r\n<p class=\"western\" lang=\"en-US\" align=\"left\"><strong>Start Date:</strong> Immediate</p>\r\n<p class=\"western\" align=\"left\"><strong><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\">JOB DUTIES:</span></span></strong></p>\r\n<p class=\"western\" lang=\"en-US\" align=\"justify\">Develop in C/C++, CUDA/ OpenCL: Focus development efforts in the C and C++ programming languages, using CUDA (Compute Unified Device Architecture) or OpenCL (Open Computing Language) API\'s to allow high performance computation on GPUs (Graphical Processing Units) of many different vendors; Develop new ArrayFire features and functionality based on market and customer needs; Optimize, analyze and profile code to ensure maximum use of hardware capabilities, including optimal usage of GPU\'s memory bandwidth and occupancy; Enhance optimization of the ArrayFire software library; Maintain ArrayFire software library interoperability with various operating systems and hardware architectures; Assist in ArrayFire development roadmap to ensure new releases are compatible with the latest hardware and software available on the market; Maintain ArrayFire documentation; Ensure quality assurance of ArrayFire software library; Develop effective QA testing and debugging procedures, ensuring ArrayFire will maintain a robust and high level of functionality; Develop test cases that will verify and ensure ArrayFire software for correctness and performance, including during boundary situations; Participation in core-product development; Development of software and content that accompany the core product to enrich user-experience; Development and maintenance of in-house software tools and processes to ensure a smooth development cycle and efficient quality control; Handle customer projects that require code-optimization using the product; Serve as technical consultant to customers and debug/resolve issues with the product.</p>\r\n<p class=\"western\" align=\"justify\"><strong><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\">REQUIREMENTS:</span></span></strong></p>\r\n<p class=\"western\" align=\"justify\">Applicants need to have a Master’s degree (or foreign equiv.) in Computer Science or any IT related field, or any Engineering field. Knowledge of the following: C, C+, CUDA/OpenCL/ Multicore/ Parallel Programming, Architecture, GPUs/ Accelerators, Linux, P-Threads, SimD, Linear Algebra, Python.</p>\r\n<p align=\"justify\"><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\"><b>Minimum Requirements Apply To The Positions Listed Above.</b></span></span></p>\r\n<p class=\"western\" align=\"left\"><span style=\"color: #000000;\"><span style=\"font-family: Verdana,sans-serif;\"><span style=\"font-size: xx-small;\"><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\">Please Refer To This Advertisement. No Phone Calls Please. Equal Opportunity Employer.</span></span></span></span></span></p>\r\n<p class=\"western\"><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\"><u>Please Mail Your Resume To:</u></span></span></p>\r\n<p class=\"western\" align=\"left\"><span style=\"font-family: Tahoma,sans-serif;\"><span style=\"font-size: small;\"><b>HR Manager</b></span></span></p>\r\n<p class=\"western\" align=\"left\">AccelerEyes, LLC</p>\r\n<p class=\"western\" align=\"left\">3405 Piedmont Road NE, Suite 100</p>\r\n<p class=\"western\" align=\"left\">Atlanta, GA 30305</p>\r\n[/column]\r\n\r\n[/content_band]','Company','','inherit','open','closed','','329-revision-v1','','','2015-11-13 21:16:04','2015-11-13 21:16:04','',329,'http://sandbox.arrayfire.com/329-revision-v1/',0,'revision','',0),(8662,18528,'2015-11-17 23:14:36','2015-11-17 23:14:36','Its hard to believe, but our ArrayFire accelerated computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed over the last year.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nAlso, SLOCCount estimates that the labor costs for ArrayFire v3.2 based on line count alone to be $3,168,838, probably using heuristics based on the number of lines of code. We found that estimate amusingly low because building a high-performance parallel computing library is much harder per line of code than most other software development projects.\r\n\r\nIn the last year we have added so many new functions, including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for ArrayFire and its OpenCL dependencies and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a> created Gentoo packages for ArrayFire and its OpenCL dependencies.</li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a>.</li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started; it\'s a great place to get jump in)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nLeading up to one year ago, we had much debate among our team as to whether or not we should open source ArrayFire. The immediate business impact was quite clear: we would lose considerable short-term revenue by giving our software away for free and the long-term revenue return was not at all evident. It could have been economic disaster for our company. However, we trusted on the goodness of the open source business model, which <a href=\"http://notonlyluck.com/?s=open+source\">John has blogged about on numerous occasions</a>, and we diversified our revenue-generating activity while still devoting tremendous resources into maintaining the open source repository.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which kept us strong. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses and government institutions.\r\n\r\nFor example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverables. Many clients hire us on retainers so our engineers can immediately begin work on new projects and become a working part of their teams.\r\n\r\nOverall, making ArrayFire open-source has been beneficial for our company. A year ago, we weathered what could have been a sudden drop in sales revenue and adapted our business model to provide services, support, and training wrapped around our open source offering. Today we stand stronger than ever and excited about continuing our business in the dynamic and community-focused approach of our open source business model.','ArrayFire: Open-source for one year!','','publish','open','closed','','arrayfire-open-source-for-one-year','','','2015-11-17 23:14:36','2015-11-17 23:14:36','',0,'http://sandbox.arrayfire.com/?p=8662',0,'post','',0),(8663,18528,'2015-11-14 20:17:34','2015-11-14 20:17:34','Its hard to believe, but our ArrayFire GPU computing library has been open-source software for one year.\r\n<h3>One year of  development: comparing 3.0 beta to 3.2</h3>\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n&nbsp;','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-14 20:17:34','2015-11-14 20:17:34','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8664,18528,'2015-11-14 21:12:08','2015-11-14 21:12:08','Its hard to believe, but our ArrayFire GPU computing library has been open-source for an entire year. While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n\r\n&nbsp;\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-14 21:12:08','2015-11-14 21:12:08','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8665,18528,'2015-11-14 21:39:28','2015-11-14 21:39:28','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n\r\n<a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.\r\n\r\n<a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<ul>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a>: <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a>: ArrayFire developers Pradeep and Pavan with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">jramapuram</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a>: Was recently created by <a href=\"https://github.com/royalstream\">royalstream</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a>: <a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a>: ArrayFire develpoer Pavan</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a>: ArrayFire developers Pradeep and Pavan</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a>: Is maintained by Pavan</li>\r\n</ul>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also <a href=\"https://github.com/arrayfire/arrayfire/commit/7084517cf72d9271076d17547e50fa7ae8b55370\">added two lines of code</a> which squelched over 1000+ unused function warnings from the clang compiler.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes by contributing six lines of code and fixed missing definitions for some proxy operators\r\n\r\n&nbsp;','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-14 21:39:28','2015-11-14 21:39:28','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8666,18528,'2015-11-15 01:31:16','2015-11-15 01:31:16','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n\r\n<a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.\r\n\r\n<a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<ul>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a>: <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a>: ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a>: Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a>: <a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a>: ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a>: ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a>: Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n</ul>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also <a href=\"https://github.com/arrayfire/arrayfire/commit/7084517cf72d9271076d17547e50fa7ae8b55370\">added two lines of code</a> which squelched over 1000+ unused function warnings from the clang compiler.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\n&nbsp;','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 01:31:16','2015-11-15 01:31:16','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8667,18528,'2015-11-15 01:48:58','2015-11-15 01:48:58','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n\r\n<a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.\r\n\r\n<a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<ul>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a>: <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a>: ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a>: Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a>: <a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a>: ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a>: ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a>: Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n</ul>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also squelched over 1000+ unused function warnings from the clang compiler with a few lines of code.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\nIf we forgot to mention any contributions that we should have, it was not intentional and please let us know so that we can update the post accordingly!','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 01:48:58','2015-11-15 01:48:58','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8668,18528,'2015-11-15 02:18:58','2015-11-15 02:18:58','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n\r\n<a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.\r\n\r\n<a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<ul>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a>: <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a>: ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a>: Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a>: <a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a>: ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a>: ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a>: Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n</ul>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also squelched over 1000+ unused function warnings from the clang compiler with a few lines of code.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\nIf we forgot to mention any contributions that we should have, it was not intentional and please let us know so that we can update the post accordingly!','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 02:18:58','2015-11-15 02:18:58','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8670,18528,'2015-11-15 14:54:23','2015-11-15 14:54:23','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<ul>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a>: <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a>: ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a>: Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a>: <a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a>: ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a>: ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n	<li><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a>: Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></li>\r\n</ul>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also squelched over 1000+ unused function warnings from the clang compiler with a few lines of code.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\nIf we forgot to mention any contributions that we should have, it was not intentional and please let us know so that we can update the post accordingly!','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 14:54:23','2015-11-15 14:54:23','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8671,18528,'2015-11-15 15:09:43','2015-11-15 15:09:43','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew Formula for installing ArrayFire on OSX from source which was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also squelched over 1000+ unused function warnings from the clang compiler with a few lines of code.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\nIf we forgot to mention any contributions that we should have, it was not intentional and please let us know so that we can update the post accordingly!','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 15:09:43','2015-11-15 15:09:43','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8672,18528,'2015-11-15 15:11:51','2015-11-15 15:11:51','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew formulae for installing ArrayFire on OSX. Hugues\' formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Code improvement</h4>\r\n<a href=\"https://github.com/glehmann\">Gaëtan Lehmann</a> added <a href=\"http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file\">CMake project configuration files</a> which automatically create the equivilant of CMake find scripts. This let us remove our (manually maintained) <code>FindArrayFire.cmake</code> script. Gaëtan also squelched over 1000+ unused function warnings from the clang compiler with a few lines of code.\r\n\r\n<a href=\"https://github.com/nathanjackson\">Nathan Jackson</a> discovered and fixed a race condition in a reduction kernel.\r\n\r\n<a href=\"https://github.com/FilipeMaia\">Filipe Maia</a> added support for <code>s64</code> and <code>u64 </code>datatypes and fixed missing definitions for some proxy operators.\r\n\r\nIf we forgot to mention any contributions that we should have, it was not intentional and please let us know so that we can update the post accordingly!','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-15 15:11:51','2015-11-15 15:11:51','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8673,18528,'2015-11-17 16:29:53','2015-11-17 16:29:53','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew formulae for installing ArrayFire on OSX. Hugues\' formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but sometime around three months after going open source, we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements.\r\n\r\n&nbsp;\r\n\r\nFor them, our one-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>\r\n<h4></h4>','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 16:29:53','2015-11-17 16:29:53','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8674,18528,'2015-11-17 17:53:43','2015-11-17 17:53:43','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, and load/save raw images.</li>\r\n	<li>Signal processing: in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew formulae for installing ArrayFire on OSX. Hugues\' formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but sometime around three months after going open source, we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses. For example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverable; however, we do have a handful of clients which hired us on retainers so our engineers can immediately begin work on new projects.\r\n\r\nOver-all, we feel that making ArrayFire open-source was beneficial for our company. We took proper measures ahead of time to ensure we could weather a sudden drop in sales revenue and adapted our business model to provide services. Our sales department presently estimates we receive 10 customer inquiries as a result of ArrayFire every week. Considering we spend no funds on advertising and no company resources on promoting ArrayFire (beyond what you read here), the open-source experiment appears to be a success.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 17:53:43','2015-11-17 17:53:43','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8675,18528,'2015-11-17 17:56:48','2015-11-17 17:56:48','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are closure (lisp) files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew formulae for installing ArrayFire on OSX. Hugues\' formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers<a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>Is maintained by<a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but sometime around three months after going open source, we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses. For example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverable; however, we do have a handful of clients which hired us on retainers so our engineers can immediately begin work on new projects.\r\n\r\nOver-all, we feel that making ArrayFire open-source was beneficial for our company. We took proper measures ahead of time to ensure we could weather a sudden drop in sales revenue and adapted our business model to provide services. Our sales department presently estimates we receive 10 customer inquiries as a result of ArrayFire every week. Considering we spend no funds on advertising and no company resources on promoting ArrayFire (beyond what you read here), the open-source experiment appears to be a success.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 17:56:48','2015-11-17 17:56:48','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8676,18528,'2015-11-17 18:01:25','2015-11-17 18:01:25','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> created a Homebrew formulae for installing ArrayFire on OSX. Hugues\' formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses. For example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverable; however, we do have a handful of clients which hired us on retainers so our engineers can immediately begin work on new projects.\r\n\r\nOver-all, we feel that making ArrayFire open-source was beneficial for our company. We took proper measures ahead of time to ensure we could weather a sudden drop in sales revenue and adapted our business model to provide services. Our sales department presently estimates we receive 10 customer inquiries as a result of ArrayFire every week. Considering we spend no funds on advertising and no company resources on promoting ArrayFire (beyond what you read here), the open-source experiment appears to be a success.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 18:01:25','2015-11-17 18:01:25','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8677,18528,'2015-11-17 18:04:34','2015-11-17 18:04:34','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for <a href=\"https://github.com/clMathLibraries/clFFT\">clFFT</a>,<a href=\"https://github.com/clMathLibraries/clBLAS\">clBLAS</a>, and <a href=\"https://ftp-master.debian.org/new/arrayfire_3.0.1-1.html\">recently added</a> ArrayFire\'s CPU backend and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a></li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses. For example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverable; however, we do have a handful of clients which hired us on retainers so our engineers can immediately begin work on new projects.\r\n\r\nOver-all, we feel that making ArrayFire open-source was beneficial for our company. We took proper measures ahead of time to ensure we could weather a sudden drop in sales revenue and adapted our business model to provide services. Our sales department presently estimates we receive 10 customer inquiries as a result of ArrayFire every week. Considering we spend no funds on advertising and no company resources on promoting ArrayFire (beyond what you read here), the open-source experiment appears to be a success.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 18:04:34','2015-11-17 18:04:34','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8678,18528,'2015-11-17 18:09:13','2015-11-17 18:09:13','Its hard to believe, but our ArrayFire GPU computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td>Estimated Cost</td>\r\n<td>$2,891,353</td>\r\n<td>$3,168,838</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nSo in the last year contributions from <a href=\"https://github.com/arrayfire/arrayfire/graphs/contributors\">ourselves and others</a> have added approximately $300,000 in functionality to the library. By our own internal estimates, these numbers are not too far off depending if you track development back to the earliest days of our company.\r\n\r\nIn the last year we have added a ton of new functionality including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is always a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for ArrayFire and its OpenCL dependencies and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a> created Gentoo packages for ArrayFire and its OpenCL dependencies.</li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a></li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started, its a great place to get started)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nThere was much debate among the executive team on whether or not we should make ArrayFire open source software. The business impact was quite clear: we would lose considerable revenue by giving our software away for free and the return was not at all evident. To survive what could have been economic disaster for our company, we diversified. About a year  before releasing our software we pursued new consulting opportunities, applied for grants, and sought out long-term partnerships with larger companies.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which was more than enough to keep our engineers busy. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses. For example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverable; however, we do have a handful of clients which hired us on retainers so our engineers can immediately begin work on new projects.\r\n\r\nOver-all, we feel that making ArrayFire open-source was beneficial for our company. We took proper measures ahead of time to ensure we could weather a sudden drop in sales revenue and adapted our business model to provide services. Our sales department presently estimates we receive 10 customer inquiries as a result of ArrayFire every week. Considering we spend no funds on advertising and no company resources on promoting ArrayFire (beyond what you read here), the open-source experiment appears to be a success.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 18:09:13','2015-11-17 18:09:13','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8680,4,'2015-11-17 19:01:47','2015-11-17 19:01:47','Its hard to believe, but our ArrayFire accelerated computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed over the last year.\n<h3>ArrayFire the library</h3>\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\n\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>3.0 beta</th>\n<th>3.2</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>cpp</td>\n<td>59140</td>\n<td>99287</td>\n</tr>\n<tr>\n<td>opencl*</td>\n<td>4522</td>\n<td>7658</td>\n</tr>\n<tr>\n<td>ansi-c</td>\n<td>547</td>\n<td>676</td>\n</tr>\n<tr>\n<td>xml</td>\n<td>165</td>\n<td>171</td>\n</tr>\n<tr>\n<td>sh</td>\n<td>0</td>\n<td>49</td>\n</tr>\n<tr>\n<td>lines</td>\n<td>64,374</td>\n<td>107,841</td>\n</tr>\n<tr>\n<td>commits</td>\n<td>1,467</td>\n<td>3,286</td>\n</tr>\n<tr>\n<td>contributors</td>\n<td>21</td>\n<td>31</td>\n</tr>\n<tr>\n<td></td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\n\nAlso, SLOCCount estimates that the labor costs for ArrayFire v3.2 based on line count alone to be $3,168,838, probably using heuristics based on the number of lines of code. We found that estimate amusingly low because building a high-performance parallel computing library is much harder per line of code than most other software development projects.\n\nIn the last year we have added so many new functions, including:\n<ul>\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\n	<li>Language wrappers (discussed below)</li>\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\n</ul>\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\n<h3>Third-party contributions</h3>\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is a prime opportunity to reiterate our appreciation for these developers.\n<h4>Installers</h4>\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\n<ul>\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for ArrayFire and its OpenCL dependencies and submitted these to Debian upstream.</li>\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a> created Gentoo packages for ArrayFire and its OpenCL dependencies.</li>\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a>.</li>\n</ul>\n<h4>Language wrappers</h4>\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\n<table>\n<thead></thead>\n<tbody>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started; it\'s a great place to get jump in)</td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\n</tr>\n<tr>\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\n</tr>\n</tbody>\n</table>\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\n<h4>Business impact</h4>\nLeading up to one year ago, we had much debate among our team as to whether or not we should open source ArrayFire. The immediate business impact was quite clear: we would lose considerable short-term revenue by giving our software away for free and the long-term revenue return was not at all evident. It could have been economic disaster for our company. However, we trusted on the goodness of the open source business model, which <a href=\"http://notonlyluck.com/?s=open+source\">John has blogged about on numerous occasions</a>, and we diversified our revenue-generating activity while still devoting tremendous resources into maintaining the open source repository.\n\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which kept us strong. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\n\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses and government institutions.\n\nFor example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverables. Many clients hire us on retainers so our engineers can immediately begin work on new projects and become a working part of their teams.\n\nOverall, making ArrayFire open-source has been beneficial for our company. A year ago, we weathered what could have been a sudden drop in sales revenue and adapted our business model to provide services, support, and training wrapped around our open source offering. Today we stand stronger than ever and excited about continuing our business in the dynamic and free flowing world of our o','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-autosave-v1','','','2015-11-17 19:01:47','2015-11-17 19:01:47','',8662,'http://sandbox.arrayfire.com/8662-autosave-v1/',0,'revision','',0),(8681,4,'2015-11-17 19:02:38','2015-11-17 19:02:38','Its hard to believe, but our ArrayFire accelerated computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed over the last year.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n<tr>\r\n<td></td>\r\n<td></td>\r\n<td></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nAlso, SLOCCount estimates that the labor costs for ArrayFire v3.2 based on line count alone to be $3,168,838, probably using heuristics based on the number of lines of code. We found that estimate amusingly low because building a high-performance parallel computing library is much harder per line of code than most other software development projects.\r\n\r\nIn the last year we have added so many new functions, including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for ArrayFire and its OpenCL dependencies and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a> created Gentoo packages for ArrayFire and its OpenCL dependencies.</li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a>.</li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started; it\'s a great place to get jump in)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nLeading up to one year ago, we had much debate among our team as to whether or not we should open source ArrayFire. The immediate business impact was quite clear: we would lose considerable short-term revenue by giving our software away for free and the long-term revenue return was not at all evident. It could have been economic disaster for our company. However, we trusted on the goodness of the open source business model, which <a href=\"http://notonlyluck.com/?s=open+source\">John has blogged about on numerous occasions</a>, and we diversified our revenue-generating activity while still devoting tremendous resources into maintaining the open source repository.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which kept us strong. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses and government institutions.\r\n\r\nFor example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverables. Many clients hire us on retainers so our engineers can immediately begin work on new projects and become a working part of their teams.\r\n\r\nOverall, making ArrayFire open-source has been beneficial for our company. A year ago, we weathered what could have been a sudden drop in sales revenue and adapted our business model to provide services, support, and training wrapped around our open source offering. Today we stand stronger than ever and excited about continuing our business in the dynamic and community-focused approach of our open source business model.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 19:02:38','2015-11-17 19:02:38','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8682,4,'2015-11-17 19:03:09','2015-11-17 19:03:09','Its hard to believe, but our ArrayFire accelerated computing library was <a href=\"http://sandbox.arrayfire.com/arrayfire-is-now-open-source/\">open-sourced a year ago</a>! While we were packing up our booth to head to <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> my colleagues started reminiscing on how much our company and library have changed over the last year.\r\n<h3>ArrayFire the library</h3>\r\nIn terms of raw statistics, the ArrayFire library is a really active project given that GPU computing is still seen as a niche field. Since its inception, ArrayFire has received 3285 commits from 31 developers (11 of which are our employees) and  produced nine (public) releases. At present we have 84 watchers, 1141 stars, and 160 forks of our code. In the last year we have had a total of 1105 opened issues. Of these, 427 are closed, 577 are closed pull requests, and 90 remain open.\r\n\r\nUsing the popular <a href=\"http://www.dwheeler.com/sloccount/\">SLOCCount</a> program, we can get a lot of interesting statistical information about the ArrayFire library including the number of lines of code per source type and approximate cost of development:\r\n<table>\r\n<thead>\r\n<tr>\r\n<th>Metric</th>\r\n<th>3.0 beta</th>\r\n<th>3.2</th>\r\n</tr>\r\n</thead>\r\n<tbody>\r\n<tr>\r\n<td>cpp</td>\r\n<td>59140</td>\r\n<td>99287</td>\r\n</tr>\r\n<tr>\r\n<td>opencl*</td>\r\n<td>4522</td>\r\n<td>7658</td>\r\n</tr>\r\n<tr>\r\n<td>ansi-c</td>\r\n<td>547</td>\r\n<td>676</td>\r\n</tr>\r\n<tr>\r\n<td>xml</td>\r\n<td>165</td>\r\n<td>171</td>\r\n</tr>\r\n<tr>\r\n<td>sh</td>\r\n<td>0</td>\r\n<td>49</td>\r\n</tr>\r\n<tr>\r\n<td>lines</td>\r\n<td>64,374</td>\r\n<td>107,841</td>\r\n</tr>\r\n<tr>\r\n<td>commits</td>\r\n<td>1,467</td>\r\n<td>3,286</td>\r\n</tr>\r\n<tr>\r\n<td>contributors</td>\r\n<td>21</td>\r\n<td>31</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\n* Note: SLOCCount thinks our OpenCL kernels (.cl) are lisp files.\r\n\r\nAlso, SLOCCount estimates that the labor costs for ArrayFire v3.2 based on line count alone to be $3,168,838, probably using heuristics based on the number of lines of code. We found that estimate amusingly low because building a high-performance parallel computing library is much harder per line of code than most other software development projects.\r\n\r\nIn the last year we have added so many new functions, including:\r\n<ul>\r\n	<li>Computer vision: FAST, ORB, Nearest Neighbor, Harris, SUSAN,  SIFT, Difference of Gaussians, Homography, and GLOH</li>\r\n	<li>Image processing: Convolution, DFT, template matching, SOBEL, colorspace conversion, erosion, wrapping, unwrapping, summed area of tables, load/save raw images, and in-place FFTs</li>\r\n	<li>Linear algebra: Matrix multiplcication, in-place factorization, solving routines, single value decomposition.</li>\r\n	<li>Installers: new packaging for Windows, Linux, and OSX installers.</li>\r\n	<li>Language wrappers (discussed below)</li>\r\n	<li>Graphics: Created an integrated our new graphics library, <a href=\"https://github.com/arrayfire/forge\">Forge</a>, into ArrayFire.</li>\r\n	<li>Datatypes: Support for 16- and 64-bit integers.</li>\r\n</ul>\r\nAnd a wealth of other functionality including support for 16-bit integers, graphics, a unified backend, and convenience debugging/printing functions.\r\n<h3>Third-party contributions</h3>\r\nI have previously written about <a href=\"http://sandbox.arrayfire.com/open-source-benefits-contributors/\">several large contributions to ArrayFire</a>, but a one-year review is a prime opportunity to reiterate our appreciation for these developers.\r\n<h4>Installers</h4>\r\nAlthough we now recommend <a href=\"http://sandbox.arrayfire.com/download/\">using our installers for Windows, Linux and OSX</a> due to their integration of Intel Math Kernel Library to accelerate linear algebra functions, we are still grateful for early packaging and distribution work provided by a few key developers.\r\n<ul>\r\n	<li>Debian: <a href=\"https://github.com/ghisvail\">Ghislain Antony Vaillant</a> created Debian packages for ArrayFire and its OpenCL dependencies and submitted these to Debian upstream.</li>\r\n	<li>Homebrew / OSX: <a href=\"https://github.com/glehmann\" target=\"https://github.com/glehmann\" rel=\"noreferrer\" data-referer-safe=\"1\">Gaëtan Lehmann</a> and <a href=\"https://github.com/hmalphettes\">Hugues Malphettes</a> (independently) created a Homebrew formulae for installing ArrayFire on OSX. Ghislain\'s formula was accepted into the official <a href=\"https://github.com/Homebrew/homebrew-science\">homebrew-science</a> repository.</li>\r\n	<li>Gentoo: <a href=\"https://github.com/marbre?tab=activity\">Marius Brehler</a> created Gentoo packages for ArrayFire and its OpenCL dependencies.</li>\r\n	<li>Arch: <a href=\"https://github.com/svenstaro?tab=repositories\">Sven-Hendrik Haase</a>.</li>\r\n</ul>\r\n<h4>Language wrappers</h4>\r\nAlthough ArrayFire is principally a C/C++ library, we ensured the C API was sufficiently complete to create wrappers for other languages. To highlight the most active repositories:\r\n<table>\r\n<thead></thead>\r\n<tbody>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-js\">Javascript</a></td>\r\n<td> <a href=\"https://github.com/unbornchikken\">Gábor Mező</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-rust\">Rust</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> with substantial contributions from <a class=\"aname\" href=\"https://github.com/jramapuram\">Jason Ramapuram</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-dotnet\">.NET</a></td>\r\n<td>Was recently created by <a href=\"https://github.com/royalstream\">Steven Burns</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-go\">GO</a></td>\r\n<td><a href=\"https://github.com/rabarar\">Rob Baruch</a> (this project just started; it\'s a great place to get jump in)</td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-java\">Java</a></td>\r\n<td>ArrayFire developers <a href=\"https://github.com/9prady9\">Pradeep Garigipati</a> and <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-r\">R</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n<tr>\r\n<td><a href=\"https://github.com/arrayfire/arrayfire-fortran\">Fortran</a></td>\r\n<td>ArrayFire developer <a href=\"https://github.com/pavanky\">Pavan Yalamanchili</a></td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nCheck out ArrayFire\'s <a href=\"https://github.com/arrayfire/\">full list of repositories</a> for other wrappers.\r\n<h4>Business impact</h4>\r\nLeading up to one year ago, we had much debate among our team as to whether or not we should open source ArrayFire. The immediate business impact was quite clear: we would lose considerable short-term revenue by giving our software away for free and the long-term revenue return was not at all evident. It could have been economic disaster for our company. However, we trusted on the goodness of the open source business model, which <a href=\"http://notonlyluck.com/?s=open+source\">John has blogged about on numerous occasions</a>, and we diversified our revenue-generating activity while still devoting tremendous resources into maintaining the open source repository.\r\n\r\nDue to this diversification, the initial financial impact of going open source was, amusingly, \"no impact at all.\" We had several long-term clients and a handful of grants which kept us strong. For the first few months the most noticeable impact we saw was a significant uptick in website traffic, support forum posts, and downloads due to prominent articles on social media. In fact, at one point ArrayFire was #2 on <a href=\"https://news.ycombinator.com/\">HackerNews</a>, being ousted from the #1 spot only by <a href=\"https://en.wikipedia.org/wiki/Philae_(spacecraft)\">ESA\'s Rosetta-Philae spacecraft</a> (which just made history by successfully harpooning a comet).\r\n\r\nI don\'t recall the precise date when it happened, but when we received our first client that specifically said that they contacted us \"because of your open-source ArrayFire library.\" We were ecstatic. Since then business due to open-source has grown appreciably. At first many of our customers were academics or small startups which were interested in short-term engagements. Now we see a fairly good mix of short and long-term engagements from a variety of businesses and government institutions.\r\n\r\nFor example, many small companies ask us to review their code to see what could be accelerated under our 1-day <a href=\"http://sandbox.arrayfire.com/consulting/\">Starter Package</a>. Often these customers come back and ask us to implement the suggestions we put forth. Meanwhile larger companies often seek fixed-fee engagements for well-defined deliverables. Many clients hire us on retainers so our engineers can immediately begin work on new projects and become a working part of their teams.\r\n\r\nOverall, making ArrayFire open-source has been beneficial for our company. A year ago, we weathered what could have been a sudden drop in sales revenue and adapted our business model to provide services, support, and training wrapped around our open source offering. Today we stand stronger than ever and excited about continuing our business in the dynamic and community-focused approach of our open source business model.','ArrayFire: Open-source for one year!','','inherit','open','closed','','8662-revision-v1','','','2015-11-17 19:03:09','2015-11-17 19:03:09','',8662,'http://sandbox.arrayfire.com/8662-revision-v1/',0,'revision','',0),(8684,18528,'2015-11-17 21:56:39','2015-11-17 21:56:39','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a>, ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015, <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL. We helped Xilinx test and improve its OpenCL implementation and make it more accessible to first-time users.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. FAST finds corners in image. In the image below, the left side shows a frame from the <a href=\"http://www.blender.org/\">Blender Foundation</a>\'s <a href=\"http://www.bigbuckbunny.org/\">Big Buck Bunny</a> video. On the right, we show the same frame but with detected corners superimposed (the green circles most obviously seen on the character\'s faces). These features, when combined with homography, can be used for object tracking.\r\n\r\nWe\'ll include more details about performance in a later blog post. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','publish','open','closed','','feature-detection-on-xilinx-fpgas-using-opencl','','','2015-11-17 21:56:39','2015-11-17 21:56:39','',0,'http://sandbox.arrayfire.com/?p=8684',0,'post','',0),(8685,18528,'2015-11-17 20:57:00','2015-11-17 20:57:00','','snapshot1','','inherit','open','closed','','snapshot1','','','2015-11-17 20:57:00','2015-11-17 20:57:00','',8684,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot1.png',0,'attachment','image/png',0),(8686,18528,'2015-11-17 21:22:31','2015-11-17 21:22:31','','FAST on a Xilinx FPGA','','inherit','open','closed','','snapshot1-2','','','2015-11-17 21:22:49','2015-11-17 21:22:49','',8684,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot11.png',0,'attachment','image/png',0),(8687,18528,'2015-11-17 21:23:16','2015-11-17 21:23:16','','FAST on a Xilinx FPGA','','inherit','open','closed','','snapshot1-3','','','2015-11-17 21:23:24','2015-11-17 21:23:24','',8684,'http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png',0,'attachment','image/png',0),(8688,18528,'2015-11-17 21:26:31','2015-11-17 21:26:31','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015 <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL.\r\n\r\nOver the last few months we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. We\'ll include more details later, but for now I\'ve included a screenshot below. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:26:31','2015-11-17 21:26:31','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8691,18528,'2015-11-17 21:30:43','2015-11-17 21:30:43','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a> ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015 <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. We\'ll include more details later, but for now I\'ve included a screenshot below. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:30:43','2015-11-17 21:30:43','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8692,18528,'2015-11-17 21:31:00','2015-11-17 21:31:00','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a>, ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015 <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. We\'ll include more details later, but for now I\'ve included a screenshot below. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:31:00','2015-11-17 21:31:00','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8693,18528,'2015-11-17 21:32:33','2015-11-17 21:32:33','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a>, ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015, <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. We\'ll include more details later, but for now I\'ve included a screenshot below. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:32:33','2015-11-17 21:32:33','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8694,18528,'2015-11-17 21:40:08','2015-11-17 21:40:08','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a>, ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015, <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. FAST finds corners in image. In the image below, the left side shows a frame from the <a href=\"http://www.blender.org/\">Blender Foundation</a>\'s <a href=\"http://www.bigbuckbunny.org/\">Big Buck Bunny</a> video. On the right, we show the same frame but with detected corners superimposed (the green circles most obviously seen on the character\'s faces). These features, when combined with homography, can be used for object tracking.\r\n\r\nWe\'ll include more details about performance in a later blog post. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:40:08','2015-11-17 21:40:08','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8695,18528,'2015-11-17 21:52:12','2015-11-17 21:52:12','Today at <a href=\"http://sandbox.arrayfire.com/arrayfire-at-sc15/\">SuperComputing 2015</a>, ArrayFire demonstrated its first FPGA-accelerated application running on a Xilinx FPGA using OpenCL. In May 2015, <a href=\"http://press.xilinx.com/2015-05-26-New-Release-of-the-SDAccel-Development-Environment-Accelerates-Data-Center-Applications-with-Expanded-Ecosystem-of-Platforms-Libraries-and-Design-Services\">ArrayFire became a Xilinx Alliance member</a> which provided us early access to the <a href=\"http://www.xilinx.com/products/design-tools/software-zone/sdaccel.html\">Xilinx SDAccel Development Environment</a> within initial support for OpenCL. We helped Xilinx test and improve its OpenCL implementation and make it more accessible to first-time users.\r\n\r\nOver the last few months, we implemented several programs for the FPGA and subsequently learned a lot about optimizing OpenCL kernels to take advantage of pipelining, wide memory busses, and the various forms of configurable local memory offered on Xilinx hardware.\r\n\r\nOur first fully ported application is from computer vision: the <a href=\"http://www.springerlink.com/index/10.1007/11744023\">FAST</a> feature extractor. FAST finds corners in image. In the image below, the left side shows a frame from the <a href=\"http://www.blender.org/\">Blender Foundation</a>\'s <a href=\"http://www.bigbuckbunny.org/\">Big Buck Bunny</a> video. On the right, we show the same frame but with detected corners superimposed (the green circles most obviously seen on the character\'s faces). These features, when combined with homography, can be used for object tracking.\r\n\r\nWe\'ll include more details about performance in a later blog post. To see it in action stop by booth 2229 at SC15!\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12.png\"><img class=\"aligncenter size-large wp-image-8687\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/11/snapshot12-1024x609.png\" alt=\"FAST on a Xilinx FPGA\" width=\"742\" height=\"441\" /></a>','Feature detection on Xilinx FPGAs using OpenCL','','inherit','open','closed','','8684-revision-v1','','','2015-11-17 21:52:12','2015-11-17 21:52:12','',8684,'http://sandbox.arrayfire.com/8684-revision-v1/',0,'revision','',0),(8698,18673,'2016-06-14 10:00:02','2016-06-14 14:00:02','The ArrayFire library attempts to make high-performance computing as easy as possible for scientists and engineers. Because many tasks need to be visualized, ArrayFire also provides a high-level interface to our <a href=\"https://github.com/arrayfire/forge\">Forge visualization library</a>. In today\'s \"<a href=\"http://sandbox.arrayfire.com/tag/learning-arrayfire-from-scratch/\">Learning ArrayFire from scratch</a>\" post we present an overview of ArrayFire\'s visualization functionality and demonstrate how to use Forge to display data contained in af::array objects.\r\n\r\n<!--more-->\r\n\r\nThe Forge library is a general-purpose visualization tool for data stored on the GPU or related accelerator devices. By default, ArrayFire ships with Forge built in. However; if you or your system administrator installed the \"no-graphics\" version of ArrayFire, Forge won\'t be included.\r\n\r\nArrayFire provides several wrapper functions that simplify Forge\'s interface when used with <a class=\"el\" title=\"A multi dimensional data container. \" href=\"classaf_1_1array.htm\">af::array</a> objects. These functions primarily perform interop tasks including visualization range setting, copying data into OpenGL data structures, and generating an OpenGL window for display.\r\n<h4><a id=\"setup\" class=\"anchor\"></a>Setup</h4>\r\nBefore we can use Forge, we must create an window containing an OpenGL context. Creating an instance of the<code><a class=\"el\" title=\"Window object to render af::arrays. \" href=\"classaf_1_1Window.htm\">af::Window</a></code> class will accomplish both of these tasks. Note, at present Forge must create and manage its own OpenGL context; however, we hope to change this in a future release. Once the window is created, you can use Forge\'s drawing functions to visualize your data. Here is a basic example of how to create a window, set its title, and enter into a drawing loop:\r\n<div class=\"fragment\">\r\n<div class=\"line\">\r\n<pre class=\"lang:default decode:true \">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n \r\ndo{\r\n \r\n//drawing functions here\r\n \r\n} while( !window.close() );</pre>\r\n</div>\r\n</div>\r\n<h4><a id=\"render_func\" class=\"anchor\"></a>Rendering Functions</h4>\r\nAs included in ArrayFire 3.3, Forge provides the following plotting capabilities:\r\n<table class=\"doxtable\">\r\n<tbody>\r\n<tr>\r\n<th>Function</th>\r\n<th>Description</th>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input array as a histogram to the window. \" href=\"group__gfx__func__draw.htm#gafd7d94aa8f5fd37fee0662a4906a38d7\">af::Window::hist()</a></td>\r\n<td>Creates a histogram plot from input data and bins</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input array as an image to the window. \" href=\"group__gfx__func__draw.htm#gaed174450be6db4dfa5ef65b7baccbe57\">af::Window::image()</a></td>\r\n<td>Display an image</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input arrays as a 2D plot to the window. \" href=\"group__gfx__func__draw.htm#ga8e01736df3d805a5488c609e2573818b\">af::Window::plot()</a></td>\r\n<td>2D Line plot</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input array as an 3d line plot to the window. \" href=\"group__gfx__func__draw.htm#ga8e04ec129034e9fe769f3e6b14cd087f\">af::Window::plot3()</a></td>\r\n<td>3D line plot</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input arrays as a 2D scatter-plot to the window. \" href=\"group__gfx__func__draw.htm#ga73406db589e5090c051baae0af175df9\">af::Window::scatter()</a></td>\r\n<td>2D scatter plot</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input arrays as a 3D scatter-plot to the window. \" href=\"group__gfx__func__draw.htm#ga3bbfbe1b60741a259d2146b3ab50ace3\">af::Window::scatter3()</a></td>\r\n<td>3D scatter plot</td>\r\n</tr>\r\n<tr>\r\n<td><a class=\"el\" title=\"Renders the input arrays as a 3D surface plot to the window. \" href=\"group__gfx__func__draw.htm#ga1cdb8c3205d70d8feaddd8c30245393f\">af::Window::surface()</a></td>\r\n<td>Visualize a 3D surface</td>\r\n</tr>\r\n</tbody>\r\n</table>\r\nFull documentation on all plotting functions can be found in the <a class=\"el\" href=\"group__gfx__func__draw.htm\">rendering functions</a> portion of the documentation.\r\n<h5><a id=\"Image_38\"></a>Image</h5>\r\nThe af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img class=\"aligncenter size-medium wp-image-8710\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" /></a>\r\n\r\nTweaking the previous example by giving our image a depth of 3 for the RGB values allows us to generate colorful noise:\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img class=\"aligncenter size-medium wp-image-8708\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" /></a>\r\n\r\nNote that Forge automatically handles any af::array type passed from Arrayfire. In the first example we passed in an image of floats in the range [0, 1]. In the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.\r\n<h5><a id=\"Plot_63\"></a>Plot</h5>\r\nThe af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see a simple example:\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png\"><img class=\"aligncenter size-medium wp-image-8714\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot-296x300.png\" alt=\"Forge 2d line plot of sin() function\" width=\"296\" height=\"300\" /></a>\r\nThe plot function has the signature:\r\n\r\n<code><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></code>\r\n\r\nBoth the x and y coordinates of the points are required to plot. This allows for non-uniform, or parametric plots:\r\n<pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png\"><img class=\"aligncenter size-medium wp-image-8707\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot-290x300.png\" alt=\"\" width=\"290\" height=\"300\" /></a>\r\n<h5><a id=\"Scatter_88\"></a>Scatter</h5>\r\nThe af::Window::scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:\r\n<pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png\"><img class=\"aligncenter size-medium wp-image-8715\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter-300x228.png\" alt=\"Forge 2d scatter plot\" width=\"300\" height=\"228\" /></a>\r\n\r\nThe scatter function has the signature:\r\n\r\n<code><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></code>\r\n\r\nThe <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img class=\"aligncenter size-full wp-image-8709\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" /></a>\r\n<h5><a id=\"Plot3_118\"></a>Plot3</h5>\r\nThe af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:\r\n\r\n<code><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></code>\r\n\r\nThe input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png\"><img class=\"aligncenter size-medium wp-image-8716\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3-300x211.png\" alt=\"Forge 3d line plot\" width=\"300\" height=\"211\" /></a>\r\n<h5><a id=\"Histogram_140\"></a>Histogram</h5>\r\nThe af::Window::hist() function renders an input array as a histogram. In our example, the input array will be created with Arrayfire’s histogram() function, which actually counts and bins each sample. The output from histogram() can directly be fed into the af::Window::hist() rendering function.\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\nIn addition to the histogram array with the number of samples in each bin, the af::Window::hist() function takes two additional parameters – the minimum and maximum values of all datapoints in the histogram array. This effectively sets the range of the binned data. The full signature of af::Window::hist() is:\r\n\r\n<code><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></code>\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png\"><img class=\"aligncenter size-medium wp-image-8711\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram-300x256.png\" alt=\"Forge histogram plot\" width=\"300\" height=\"256\" /></a>\r\n<h5><a id=\"Scatter3_162\"></a>Scatter3</h5>\r\nThe af::Window::scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:\r\n\r\n<code><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></code>\r\n\r\nThe input array expects xyz-triplets in sequential order. The points can be in a flattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.\r\n\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png\"><img class=\"aligncenter size-medium wp-image-8712\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3-300x208.png\" alt=\"Forge 3d scatter plot\" width=\"300\" height=\"208\" /></a>\r\n<pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\nThe <strong>af::markerType</strong> enum determines which marker will be drawn at each point. It can take on the values of:\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\"><img class=\"aligncenter size-full wp-image-8709\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png\" alt=\"Different types of markers in Forge.\" width=\"1846\" height=\"326\" /></a>\r\n<h5><a id=\"Surface_195\"></a>Surface</h5>\r\nThe af::Window::surface() function will plot af::arrays as a 3d surface.\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png\"><img class=\"aligncenter size-medium wp-image-8713\" src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface-300x269.png\" alt=\"Forge 3d surface() plot\" width=\"300\" height=\"269\" /></a>\r\nThere are two overloads for the af::Window::surface() function:\r\n\r\n<code><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</code>\r\n\r\n<code><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</code>\r\n\r\nThe second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:\r\n<ol>\r\n 	<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n 	<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h4><a id=\"Conclusion_216\"></a>Conclusion</h4>\r\nThere is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as robust as the rest of the Arrayfire library.','Visualizing the af::array with Forge','','publish','open','closed','','visualizing-arrays-with-forge','','','2016-12-29 19:24:43','2016-12-30 00:24:43','',0,'http://sandbox.arrayfire.com/?p=8698',0,'post','',0),(8699,18673,'2015-12-03 00:12:15','2015-12-03 00:12:15','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for\r\nhigh-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization\r\nlibrary, is to provide equally robust visualizations that are interoperable\r\nbetween Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface\r\nto visualize af::arrays. These functions perform various interoperability tasks. One in\r\nparticular is that instead of wasting time copying and reformatting data from\r\nthe GPU to the host and back to the GPU, we can draw directly from GPU-data to\r\nGPU-framebuffers! This saves 2 memory copies.</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire\r\nanneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-keyword\">const</span> <span class=\"hljs-keyword\">static</span> <span class=\"hljs-keyword\">int</span> width = <span class=\"hljs-number\">512</span>, height = <span class=\"hljs-number\">512</span>;\r\naf::<span class=\"hljs-function\">Window <span class=\"hljs-title\">window</span><span class=\"hljs-params\">(width, height, <span class=\"hljs-string\">\"2D plot example title\"</span>)</span></span>;\r\n\r\n<span class=\"hljs-keyword\">do</span>{\r\n\r\n<span class=\"hljs-comment\">//drawing functions here</span>\r\n\r\n} <span class=\"hljs-keyword\">while</span>( !window.close() );\r\n</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to\r\ndraw to the window.\r\nThe drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img =<span class=\"hljs-function\"> constant(</span>0, width, height<span class=\"hljs-function\">)</span>; //make a black image<span class=\"hljs-instruction\">\r\narray </span>random =<span class=\"hljs-function\"> randu(</span>width, height<span class=\"hljs-function\">)</span>;      //make random <span class=\"hljs-keyword\">[</span>0,1] distribution\r\n\r\nwindow.image(img<span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-built_in\">array</span> img = <span class=\"hljs-number\">255</span> * randu(width, height, <span class=\"hljs-number\">3</span>);      <span class=\"hljs-comment\">//make random [0, 255] distribution</span>\r\nwindow.image( img.as(u8) );\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X =<span class=\"hljs-function\"> seq(</span>-af::Pi, af::Pi, 0.01<span class=\"hljs-function\">)</span>;<span class=\"hljs-instruction\">\r\narray </span>Y =<span class=\"hljs-function\"> sin(</span>X<span class=\"hljs-function\">)</span>;\r\nwindow.plot(X, Y<span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-built_in\">array</span> t = seq(<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">100</span>, <span class=\"hljs-number\">0.01</span>);\r\n<span class=\"hljs-built_in\">array</span> X = <span class=\"hljs-built_in\">sin</span>(t) * (<span class=\"hljs-built_in\">exp</span>(<span class=\"hljs-built_in\">cos</span>(t)) - <span class=\"hljs-number\">2</span> * <span class=\"hljs-built_in\">cos</span>(<span class=\"hljs-number\">4</span> * t) - <span class=\"hljs-built_in\">pow</span>(<span class=\"hljs-built_in\">sin</span>(t / <span class=\"hljs-number\">12</span>), <span class=\"hljs-number\">5</span>));\r\n<span class=\"hljs-built_in\">array</span> Y = <span class=\"hljs-built_in\">cos</span>(t) * (<span class=\"hljs-built_in\">exp</span>(<span class=\"hljs-built_in\">cos</span>(t)) - <span class=\"hljs-number\">2</span> * <span class=\"hljs-built_in\">cos</span>(<span class=\"hljs-number\">4</span> * t) - <span class=\"hljs-built_in\">pow</span>(<span class=\"hljs-built_in\">sin</span>(t / <span class=\"hljs-number\">12</span>), <span class=\"hljs-number\">5</span>));\r\nwindow.plot(X, Y);\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p>\r\n<pre><code class=\"language-{.cpp}\">array X =<span class=\"hljs-function\"> seq(</span>-af::Pi, af::Pi, 0.01<span class=\"hljs-function\">)</span>;<span class=\"hljs-instruction\">\r\narray </span>noise =<span class=\"hljs-function\"> randn(</span>X.dims(0<span class=\"hljs-function\">)</span><span class=\"hljs-function\">)</span> /3.0f;<span class=\"hljs-instruction\">\r\narray </span>Y =<span class=\"hljs-function\"> sin(</span>X<span class=\"hljs-function\">)</span> + noise;\r\nwindow.scatter(X, Y<span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">enum</span> <span class=\"hljs-title\">af::markerType</span> {</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_POINT</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_CIRCLE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_SQUARE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_TRIANGLE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_CROSS</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_PLUS</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_STAR</span>\r\n};\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z =<span class=\"hljs-function\"> seq(</span>0.1f, 10.f, 0.01<span class=\"hljs-function\">)</span>;<span class=\"hljs-instruction\">\r\narray </span>Y =<span class=\"hljs-function\"> sin(</span>10 * Z<span class=\"hljs-function\">)</span> / Z;<span class=\"hljs-instruction\">\r\narray </span>X =<span class=\"hljs-function\"> cos(</span>10 * Z<span class=\"hljs-function\">)</span> / Z;\r\n<span class=\"hljs-instruction\">\r\narray </span>Pts =<span class=\"hljs-function\"> join(</span>1, X, Y, Z<span class=\"hljs-function\">)</span>;\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet<span class=\"hljs-instruction\"> array </span>with size 3n x 1\r\nwindow.plot3(Pts<span class=\"hljs-function\">)</span>;\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts<span class=\"hljs-function\">)</span><span class=\"hljs-function\">)</span>;\r\n//window.plot3(flat(Pts<span class=\"hljs-function\">)</span><span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const<span class=\"hljs-instruction\"> int </span>BINS = 128; SAMP<span class=\"hljs-class\">LES = 9162;</span><span class=\"hljs-instruction\">\r\narray </span>norm =<span class=\"hljs-function\"> randn(</span>SAMP<span class=\"hljs-class\">LES);</span><span class=\"hljs-instruction\">\r\narray </span>hist_arr =<span class=\"hljs-function\"> histogram(</span>norm, BINS<span class=\"hljs-function\">)</span>;\r\n\r\nwin.hist(hist_arr, 0, BINS<span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<pre><code class=\"language-{.cpp}\">array X =<span class=\"hljs-function\"> randn(</span>300<span class=\"hljs-function\">)</span>;<span class=\"hljs-instruction\">\r\narray </span>Y =<span class=\"hljs-function\"> randn(</span>300<span class=\"hljs-function\">)</span>;<span class=\"hljs-instruction\">\r\narray </span>Z =<span class=\"hljs-function\"> randn(</span>300<span class=\"hljs-function\">)</span>;\r\n<span class=\"hljs-instruction\">\r\narray </span>Pts =<span class=\"hljs-function\"> join(</span>1, X, Y, Z<span class=\"hljs-function\">)</span>;\r\nwindow.scatter3(Pts<span class=\"hljs-function\">)</span>;\r\n</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\"><span class=\"hljs-class\"><span class=\"hljs-keyword\">enum</span> <span class=\"hljs-title\">af::markerType</span> {</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_POINT</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_CIRCLE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_SQUARE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_TRIANGLE</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_CROSS</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_PLUS</span>\r\n    <span class=\"hljs-constant\">AF_MARKER_STAR</span>\r\n};\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(<span class=\"hljs-number\">21</span>, <span class=\"hljs-number\">21</span>);\r\nwindow.surface(Z, <span class=\"hljs-string\">\"Random Surface\"</span>);    <span class=\"hljs-regexp\">//equal</span> to <span class=\"hljs-keyword\">next</span> function call\r\n//window.surface( se<span class=\"hljs-string\">q(-1, 1, 0.1)</span>, se<span class=\"hljs-string\">q(-1, 1, 0.1)</span>, Z, <span class=\"hljs-string\">\"Random Surface\"</span>);\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:12:15','2015-12-03 00:12:15','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8700,18673,'2015-12-03 00:23:57','2015-12-03 00:23:57','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for\r\nhigh-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization\r\nlibrary, is to provide equally robust visualizations that are interoperable\r\nbetween Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface\r\nto visualize af::arrays. These functions perform various interoperability tasks. One in\r\nparticular is that instead of wasting time copying and reformatting data from\r\nthe GPU to the host and back to the GPU, we can draw directly from GPU-data to\r\nGPU-framebuffers! This saves 2 memory copies.</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire\r\nanneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\nconst static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );\r\n</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to\r\ndraw to the window.\r\nThe drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\nenum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">\r\nconst int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);\r\n</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);\r\n</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\nenum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};\r\n</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");\r\n</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:23:57','2015-12-03 00:23:57','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8701,18673,'2015-12-03 00:26:30','2015-12-03 00:26:30','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for\r\nhigh-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization\r\nlibrary, is to provide equally robust visualizations that are interoperable\r\nbetween Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface\r\nto visualize af::arrays. These functions perform various interoperability tasks. One in\r\nparticular is that instead of wasting time copying and reformatting data from\r\nthe GPU to the host and back to the GPU, we can draw directly from GPU-data to\r\nGPU-framebuffers! This saves 2 memory copies.</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire\r\nanneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to\r\ndraw to the window.\r\nThe drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">\r\narray img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">\r\narray X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">\r\narray t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">\r\narray X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">\r\nenum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">\r\narray X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:26:30','2015-12-03 00:26:30','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8702,18673,'2015-12-03 00:28:06','2015-12-03 00:28:06','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for\r\nhigh-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization\r\nlibrary, is to provide equally robust visualizations that are interoperable\r\nbetween Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface\r\nto visualize af::arrays. These functions perform various interoperability tasks. One in\r\nparticular is that instead of wasting time copying and reformatting data from\r\nthe GPU to the host and back to the GPU, we can draw directly from GPU-data to\r\nGPU-framebuffers! This saves 2 memory copies.</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire\r\nanneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to\r\ndraw to the window.\r\nThe drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:28:06','2015-12-03 00:28:06','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8703,18673,'2015-12-03 00:36:51','2015-12-03 00:36:51','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to\r\ndraw to the window.\r\nThe drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:36:51','2015-12-03 00:36:51','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8704,18673,'2015-12-03 00:37:57','2015-12-03 00:37:57','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h1><a id=\"Setup_17\"></a>Setup</h1>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h1><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h1>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h2><a id=\"Image_38\"></a>Image</h2>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h2><a id=\"Plot_63\"></a>Plot</h2>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h2><a id=\"Scatter_88\"></a>Scatter</h2>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Plot3_118\"></a>Plot3</h2>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Histogram_140\"></a>Histogram</h2>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h2><a id=\"Scatter3_162\"></a>Scatter3</h2>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h2><a id=\"Surface_195\"></a>Surface</h2>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point.\r\nEach of the vectors will have length <strong>mn x 1</strong>.\r\nThis can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h1><a id=\"Conclusion_216\"></a>Conclusion</h1>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire.\r\nThanks to the high-performance gpu plotting library Forge, the provided Arrayfire\r\nfunctions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:37:57','2015-12-03 00:37:57','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8705,18673,'2015-12-03 00:42:48','2015-12-03 00:42:48','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images.\r\nTo plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height); //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:42:48','2015-12-03 00:42:48','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8706,18673,'2015-12-03 00:45:57','2015-12-03 00:45:57','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/noise.png” alt=“Forge image plot of noise” width=“20%” /&gt;</p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:45:57','2015-12-03 00:45:57','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8707,18673,'2015-12-03 00:46:50','2015-12-03 00:46:50','Forge 2d line plot of butterfly() function ','','','inherit','open','closed','','butterfly_plot','','','2015-12-03 19:26:25','2015-12-03 19:26:25','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/butterfly_plot.png',0,'attachment','image/png',0),(8708,18673,'2015-12-03 00:46:51','2015-12-03 00:46:51','','','','inherit','open','closed','','color_noise','','','2015-12-03 19:23:47','2015-12-03 19:23:47','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png',0,'attachment','image/png',0),(8709,18673,'2015-12-03 00:46:52','2015-12-03 00:46:52','','','','inherit','open','closed','','marker_types','','','2015-12-03 19:28:11','2015-12-03 19:28:11','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/marker_types.png',0,'attachment','image/png',0),(8710,18673,'2015-12-03 00:46:53','2015-12-03 00:46:53','','','','inherit','open','closed','','noise','','','2015-12-03 00:51:50','2015-12-03 00:51:50','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png',0,'attachment','image/png',0),(8711,18673,'2015-12-03 00:46:54','2015-12-03 00:46:54','','','','inherit','open','closed','','norm_histogram','','','2015-12-03 19:29:57','2015-12-03 19:29:57','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_histogram.png',0,'attachment','image/png',0),(8712,18673,'2015-12-03 00:46:55','2015-12-03 00:46:55','','','','inherit','open','closed','','norm_scatter3','','','2015-12-03 19:30:34','2015-12-03 19:30:34','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/norm_scatter3.png',0,'attachment','image/png',0),(8713,18673,'2015-12-03 00:46:56','2015-12-03 00:46:56','','','','inherit','open','closed','','rand_surface','','','2015-12-03 19:31:27','2015-12-03 19:31:27','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/rand_surface.png',0,'attachment','image/png',0),(8714,18673,'2015-12-03 00:46:56','2015-12-03 00:46:56','','','','inherit','open','closed','','sin_plot','','','2015-12-03 19:25:35','2015-12-03 19:25:35','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_plot.png',0,'attachment','image/png',0),(8715,18673,'2015-12-03 00:46:57','2015-12-03 00:46:57','','','','inherit','open','closed','','sin_scatter','','','2015-12-03 19:27:07','2015-12-03 19:27:07','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/sin_scatter.png',0,'attachment','image/png',0),(8716,18673,'2015-12-03 00:46:58','2015-12-03 00:46:58','','','','inherit','open','closed','','spiral_plot3','','','2015-12-03 19:29:09','2015-12-03 19:29:09','',8698,'http://sandbox.arrayfire.com/wp-content/uploads/2015/12/spiral_plot3.png',0,'attachment','image/png',0),(8717,18673,'2015-12-03 00:52:32','2015-12-03 00:52:32','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"alignnone size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 00:52:32','2015-12-03 00:52:32','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8718,18673,'2015-12-03 19:22:31','2015-12-03 19:22:31','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/color_noise.png” alt=“Forge image plot of color noise” width=“20%” /&gt;</p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:22:31','2015-12-03 19:22:31','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),(8719,18673,'2015-12-03 19:23:58','2015-12-03 19:23:58','<title>forgeviz.md</title>\r\n<p>Visualizing af::array with Forge</p>\r\n<p>Arrayfire as a library aims to provide a robust and easy to use platform for high-performance, parallel and GPU computing.\r\nThe goal of <a href=\"https://github.com/arrayfire/forge\">Forge</a>, an OpenGL visualization library, is to provide equally robust visualizations that are interoperable between Arrayfire data-structures and an OpenGL context.</p>\r\n<p>Arrayfire provides wrapper functions that are designed to be a simple interface to visualize af::arrays. These functions perform various interoperability tasks. One in particular is that instead of wasting time copying and reformatting data from the GPU to the host and back to the GPU, we can draw directly from GPU-data to GPU-framebuffers, saving two memory copies!</p>\r\n<p>Let’s see exactly what visuals we can illuminate with forge and how Arrayfire anneals the data between the two libraries.</p>\r\n<h2><a id=\"Setup_17\"></a>Setup</h2>\r\n<p>Before we can call Forge functions, we need to set up the related “canvas” classes.\r\nForge functions are tied to the af::Window class. First let’s create a window:</p>\r\n<pre><code class=\"language-{.cpp}\">const static int width = 512, height = 512;\r\naf::Window window(width, height, \"2D plot example title\");\r\n\r\ndo{\r\n\r\n//drawing functions here\r\n\r\n} while( !window.close() );</code></pre>\r\n<p>We also added a drawing loop, so now we can use Forge’s drawing functions to draw to the window. The drawing functions present in Forge are listed below.</p>\r\n<h2><a id=\"Rendering_Functions_35\"></a>Rendering Functions</h2>\r\n<p>Documentation for the rendering functions can be found <a href=\"http://sandbox.arrayfire.com/docs/group__gfx__func__draw.htm\">here</a> .</p>\r\n<h3><a id=\"Image_38\"></a>Image</h3>\r\n<p>The af::Window::image() function can be used to plot grayscale or color images. To plot a grayscale image a 2d array should be passed into the function.\r\nLet’s see this on a static noise example:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = constant(0, width, height);   //make a black image\r\narray random = randu(width, height);      //make random [0,1] distribution\r\n\r\nwindow.image(img);</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/noise-262x300.png\" alt=\"Forge image plot of noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8710\" /></a></p>\r\n<p>Tweaking the previous example by giving our image a depth of 3 for the RGB values\r\nallows us to generate colorful noise:</p>\r\n<pre><code class=\"language-{.cpp}\">array img = 255 * randu(width, height, 3);      //make random [0, 255] distribution\r\nwindow.image( img.as(u8) );</code></pre>\r\n<p><a href=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise.png\"><img src=\"http://sandbox.arrayfire.com/wp-content/uploads/2015/12/color_noise-262x300.png\" alt=\"Forge image plot of color noise\" width=\"262\" height=\"300\" class=\"aligncenter size-medium wp-image-8708\" /></a></p>\r\n<p>Note that Forge automatically handles any af::array type passed from Arrayfire.\r\nIn the first example we passed in an image of floats in the range [0, 1].\r\nIn the last example we cast our array to an unsigned byte array with the range\r\n[0, 255]. The type-handling properties are consistent for all Forge drawing functions.</p>\r\n<h3><a id=\"Plot_63\"></a>Plot</h3>\r\n<p>The af::Window::plot() function visualizes an array as a 2d-line plot. Let’s see\r\na simple example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray Y = sin(X);\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/sin_plot.png” alt=“Forge 2d line plot of sin() function” width=“30%” /&gt;\r\nThe plot function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void plot( const array &amp;X, const array &amp;Y, const char * const title = NULL );</strong></p>\r\n</blockquote>\r\n<p>Both the x and y coordinates of the points are required to plot. This allows for\r\nnon-uniform, or parametric plots:</p><pre><code class=\"language-{.cpp}\">array t = seq(0, 100, 0.01);\r\narray X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\narray Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));\r\nwindow.plot(X, Y);</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/butterfly_plot.png” alt=“Forge 2d line plot of butterfly function” width=“30%” /&gt;</p>\r\n<h3><a id=\"Scatter_88\"></a>Scatter</h3>\r\n<p>The scatter() function visualizes an array as a 2d-scatter plot. Let’s see a example:</p><pre><code class=\"language-{.cpp}\">array X = seq(-af::Pi, af::Pi, 0.01);\r\narray noise = randn(X.dims(0)) /3.0f;\r\narray Y = sin(X) + noise;\r\nwindow.scatter(X, Y);</code></pre>\r\n<p>&lt;img src=“forge_viz/sin_scatter.png” alt=“Forge 2d scatter plot” width=“40%” /&gt;</p>\r\n<p>The scatter function has the signature:</p>\r\n<blockquote>\r\n<p><strong>void scatter( const array &amp;X, const array &amp;Y, af::markerType marker=AF_MARKER_POINT, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p><pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Plot3_118\"></a>Plot3</h3>\r\n<p>The af::Window::plot3() function will plot a curve in 3d-space.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void plot3 (const array &amp;in, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = seq(0.1f, 10.f, 0.01);\r\narray Y = sin(10 * Z) / Z;\r\narray X = cos(10 * Z) / Z;\r\n\r\narray Pts = join(1, X, Y, Z);\r\n//Pts can be passed in as a matrix in the from n x 3, 3 x n\r\n//or in the flattened xyz-triplet array with size 3n x 1\r\nwindow.plot3(Pts);\r\n//both of the following are equally valid\r\n//window.plot3(transpose(Pts));\r\n//window.plot3(flat(Pts));</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/spiral_plot3.png” alt=“Forge 3d line plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Histogram_140\"></a>Histogram</h3>\r\n<p>The af::Window::hist() function renders an input array as a histogram.\r\nIn our example, the input array will be created with Arrayfire’s histogram()\r\nfunction, which actually counts and bins each sample. The output from histogram()\r\ncan directly be fed into the af::Window::hist() rendering function.</p>\r\n<pre><code class=\"language-{.cpp}\">const int BINS = 128; SAMPLES = 9162;\r\narray norm = randn(SAMPLES);\r\narray hist_arr = histogram(norm, BINS);\r\n\r\nwin.hist(hist_arr, 0, BINS);</code></pre>\r\n<p>In addition to the histogram array with the number of samples in each bin, the\r\naf::Window::hist() function takes two additional parameters – the minimum and\r\nmaximum values of all datapoints in the histogram array. This effectively sets\r\nthe range of the binned data. The full signature of af::Window::hist() is:</p>\r\n<blockquote>\r\n<p><strong>void hist(const array &amp; X, const double minval, const double maxval, const char * const title = NULL);</strong></p>\r\n</blockquote>\r\n<p>&lt;img src=“gfx_docs_images/norm_histogram.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p>\r\n<h3><a id=\"Scatter3_162\"></a>Scatter3</h3>\r\n<p>The scatter3() function visualizes an array as a 3d-scatter plot.\r\nIts signature is:</p>\r\n<blockquote>\r\n<p><strong>void scatter3 (const array &amp;in, af::markerType marker=AF_MARKER_POINT, const char * title = NULL);</strong></p>\r\n</blockquote>\r\n<p>The input array expects xyz-triplets in sequential order. The points can be in a\r\nflattened one dimensional (<em>3n x 1</em>) array, or in one of the (<em>3 x n</em>), (<em>n x 3</em>) matrix forms.</p>\r\n<p>&lt;img src=“forge_viz/norm_scatter3.png” alt=“Forge 3d scatter plot” width=“40%” /&gt;</p><pre><code class=\"language-{.cpp}\">array X = randn(300);\r\narray Y = randn(300);\r\narray Z = randn(300);\r\n\r\narray Pts = join(1, X, Y, Z);\r\nwindow.scatter3(Pts);</code></pre>\r\n<p>The <strong>af::markerType</strong> enum determines which marker will be drawn at each point.\r\nIt can take on the values of:</p>\r\n<pre><code class=\"language-{.cpp}\">enum af::markerType {\r\n    AF_MARKER_POINT\r\n    AF_MARKER_CIRCLE\r\n    AF_MARKER_SQUARE\r\n    AF_MARKER_TRIANGLE\r\n    AF_MARKER_CROSS\r\n    AF_MARKER_PLUS\r\n    AF_MARKER_STAR\r\n};</code></pre>\r\n<p>&lt;img src=“forge_viz/marker_types.png” alt=“Different marker types in forge” width=“100%” /&gt;</p>\r\n<h3><a id=\"Surface_195\"></a>Surface</h3>\r\n<p>The af::Window::surface() function will plot af::arrays as a 3d surface.</p>\r\n<pre><code class=\"language-{.cpp}\">array Z = randu(21, 21);\r\nwindow.surface(Z, \"Random Surface\");    //equal to next function call\r\n//window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, \"Random Surface\");</code></pre>\r\n<p>&lt;img src=“gfx_docs_images/rand_surface.png” alt=“Forge random surface plot” width=“30%” /&gt;\r\nThere are two overloads for the af::Window::surface() function:</p>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp; S, const char * const title )</strong>\r\n// Accepts a 2d matrix with the z values of the surface</p>\r\n</blockquote>\r\n<blockquote>\r\n<p><strong>void surface (const array &amp;xVals, const array &amp;yVals, const array &amp;S, const char * const title)</strong>\r\n// accepts additional vectors that define the x,y coordinates for the surface points.</p>\r\n</blockquote>\r\n<p>The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size <strong>m x n</strong>:</p>\r\n<ol>\r\n<li>Short vectors defining the spacing along each axis. Vectors will have sizes <strong>m x 1</strong> and <strong>n x 1</strong>.</li>\r\n<li>Vectors containing the coordinates of each and every point. Each of the vectors will have length <strong>mn x 1</strong>. This can be used for completely non-uniform or parametric surfaces.</li>\r\n</ol>\r\n<h2><a id=\"Conclusion_216\"></a>Conclusion</h2>\r\n<p>There is a fairly comprehensive collection of methods to visualize data in Arrayfire. Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire functions not only make visualizations as simple as possible, but keep them as\r\nrobust as the rest of the Arrayfire library.</p>\r\n','Visualizing af::array with Forge','','inherit','open','closed','','8698-revision-v1','','','2015-12-03 19:23:58','2015-12-03 19:23:58','',8698,'http://sandbox.arrayfire.com/8698-revision-v1/',0,'revision','',0),