Note that there are some explanatory texts on larger screens.

plurals
  1. POInplace updating of function arguments
    primarykey
    data
    text
    <p>I need an efficient implementation of the cartesian product for a variable number of arrays.</p> <p>I have tried the <code>product</code> function from <code>Iterators.jl</code>, but the performance was lacking.</p> <p>I am a python hacker and have used <a href="https://github.com/scikit-learn/scikit-learn/blob/9e10ec017b15f7549ba462dcd5c2bf089bc318e4/sklearn/utils/extmath.py#L493-L543" rel="nofollow">this function</a> from sklearn and have had good performance results with it.</p> <p>I have tried to write a Julia version of this function, but am not able to produce the same results as the python function.</p> <p>My code is:</p> <pre><code>function my_repeat(a, n) # mimics numpy.repeat m = size(a, 1) out = Array(eltype(a), n * m) out[1:n] = a[1] for i=2:m out[(i-1)*n+1:i*n] = a[i] end return out end function cartesian(arrs; out=None) dtype = eltype(arrs[1]) n = prod([size(i, 1) for i in arrs]) if is(out, None) out = Array(dtype, n, length(arrs)) end m = int(n / size(arrs[1], 1)) out[:, 1] = my_repeat(arrs[1], m) if length(arrs[2:]) &gt; 0 cartesian(arrs[2:], out=out[1:m, 2:]) for j = 1:size(arrs[1], 1)-1 out[(j*m + 1):(j+1)*m, 2:] = out[1:m, 2:] end end return out end </code></pre> <p>I test it with the following:</p> <pre><code>aa = ([1, 2, 3], [4, 5], [6, 7]) cartesian(aa) </code></pre> <p>The return value is:</p> <pre><code>12x3 Array{Float64,2}: 1.0 9.88131e-324 2.13149e-314 1.0 2.76235e-318 2.13149e-314 1.0 9.88131e-324 2.13676e-314 1.0 9.88131e-324 2.13676e-314 2.0 9.88131e-324 2.13149e-314 2.0 2.76235e-318 2.13149e-314 2.0 9.88131e-324 2.13676e-314 2.0 9.88131e-324 2.13676e-314 3.0 9.88131e-324 2.13149e-314 3.0 2.76235e-318 2.13149e-314 3.0 9.88131e-324 2.13676e-314 3.0 9.88131e-324 2.13676e-314 </code></pre> <p>I believe that the problem here is that when I use this line: <code>cartesian(arrs[2:], out=out[1:m, 2:])</code>, the keyword argument <code>out</code> is not updated inplace in the recursive calls. </p> <p>As can be seen, I have done a very naive translation of the Python version of this function (see link from above). It might well be possible that there are internal language differences that make a naive translation impossible. I don't think this is true because of this quote from the <a href="http://docs.julialang.org/en/latest/manual/functions/#argument-passing-behavior" rel="nofollow">functions</a> section of the julia documentation:</p> <blockquote> <p>Julia function arguments follow a convention sometimes called “pass-by-sharing”, which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values. Modifications to mutable values (such as Arrays) made within a function will be visible to the caller. This is the same behavior found in Scheme, most Lisps, Python, Ruby and Perl, among other dynamic languages.</p> </blockquote> <p>How can I make this (or an equivalent) function work in Julia?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload