100 Julia exercises

1,921 views
Skip to first unread message

Michiaki Ariga

unread,
Jun 22, 2014, 10:43:32 AM6/22/14
to julia...@googlegroups.com
Hi all,

I'm a Julia newbee, and I'm trying to learn Julia and wrote Julia version of rougier's 100 numpy exercises(http://www.loria.fr/~rougier/teaching/numpy.100/index.html).


I'd like you to tell me more "julia way" or something wrong with.

Best regards,
Michiaki

harven

unread,
Jun 22, 2014, 5:11:51 PM6/22/14
to julia...@googlegroups.com
I just had a quick look. Here are some ideas for a few exercices.

You can use list comprehension in some exercices e.g.

   Checkerboard pattern
   Float64[(i+j)%2 for i=1:8, j=1:8]

   10x10 matrix with row values ranging from 0 to 9
   Float64[j for i=0:9, j=0:9 ]

It seems that what is called a scalar type in numpy is a subtype of the Signed abstract type in Julia.
   
    Print the minimum and maximum representable value for each Julia scalar type
    print(map!(t -> (typemin(t),typemax(t)), subtypes(Signed)))

Generators can be built with closures. In what follows, I am generating the multiples of 2 in an array.

    Consider a generator function that generates 10 integers and use it to build an array
    makegen(n) = let r = 0 ; () -> (r+=n ; r) ; end ; mygen = makegen(2) ;
    [mygen() for i = 1:10]

Best,

Alireza Nejati

unread,
Jun 22, 2014, 6:35:43 PM6/22/14
to julia...@googlegroups.com
Same with Apprentice.4 :

[(x,y) for x in linspace(0,1,10), y in linspace(0,1,10)]

meshgrid() isn't included in Julia because it's almost never really needed.

Good work on these exercises, although I fear that the questions, being designed for numpy, may not accurately reflect typical julia programming patterns and idioms. While numpy and Matlab both place a lot of emphasis on vectorization, there is no need at all to vectorize many element-wise operations in Julia. In fact, vectorization often makes code both harder to read and less efficient. Although I see that you've opted for loops in some of the more advanced exercises, which is good.

Another thing is that more functional-type coding is also emphasized in julia. Here's a solution for Expert.4 (which I notice you've left empty):

reduce(+, [A*x for A in matlist, x in veclist])

Billou Bielour

unread,
Jun 23, 2014, 6:19:20 AM6/23/14
to julia...@googlegroups.com
I'm not sure and array of tuple is what you want in the meshgrid case,
I mean can you use it to compute say cos(X*Y) (which is usually what you want to use meshgrid for) ?

It's also linked to the problem of evaluating a Gaussian, the solution given here use meshgrid:

X, Y = meshgrid(linspace(-1,1,100),linspace(-1,1,100))
D = sqrtm(X*X + Y*Y)
sigma, mu = 1.0, 0.0
G = exp(-( (D.-mu)^2 / ( 2.0 * sigma^2 ) ) )

You can do it with array comprehension:

sigma, mu = 1.0, 0.0
G = [ exp(-(x-mu).^2/(2.0*sigma^2) -(y-mu).^2/(2.0*sigma^2) ) for x in linspace(-1,1,100), y in linspace(-1,1,100) ]

It look like a more elegant solution in this case, but this kind of one-liner can also become unreadable. Maybe a loop is still the most generic solution:

sigma, mu = 1.0, 0.0
x,y = linspace(-1,1,100), linspace(-1,1,100)
G = zeros(length(x),length(y))

for i in 1:length(x), j in 1:length(y)
    G[i,j] = exp(-(x[i]-mu).^2/(2.0*sigma^2) -(y[j]-mu).^2/(2.0*sigma^2) )
end


Michiaki Ariga

unread,
Jun 23, 2014, 11:31:26 AM6/23/14
to julia...@googlegroups.com
Thank you for your kind replies.

I noticed that I'm not familiar with array comprehension style in Julia.
I added your solutions to my repos.
(If you have any problem to do it, please tell me)

As Alireza said, this is just a translation from numpy, but I believe there are good questions suitable for Julia.
Why don't you propose more Julia like exercises using pull request!
(Especially, I think harven's Generators exercise is good for example.)

I have a question.

Alireza told me solution for Expert.4 as following.

> Another thing is that more functional-type coding is also emphasized in julia. Here's a solution for Expert.4 (which I notice you've left empty):
> reduce(+, [A*x for A in matlist, x in veclist])

It seems to return scalar value 800000, but original numpy version's result is as following 20x1 vector.
How can I reduce keeping array?

```
[[ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]
 [ 200.]]
```


2014年6月22日日曜日 23時43分32秒 UTC+9 Michiaki Ariga:

Alireza Nejati

unread,
Jun 23, 2014, 5:52:27 PM6/23/14
to julia...@googlegroups.com
Actually that's not a bad idea; someone should start a Julia-specific exercise repo.

About Expert.4, I'm not sure how you're running it, but matlist and veclist should obviously be lists of matrices and vectors, respectively.

matlist = Matrix[rand(4,4), rand(4,4)]
veclist = Vector[rand(4), rand(4)]

reduce(+, [A*x for A in matlist, x in veclist])


You can also try setting matlist = Matrix[rand(4,4)] and veclist = Vector[rand(4)] and it will still work.



On Monday, June 23, 2014 2:43:32 AM UTC+12, Michiaki Ariga wrote:

Jacob Quinn

unread,
Jun 23, 2014, 6:06:47 PM6/23/14
to julia...@googlegroups.com

Feel free to check out (and contribute!) to https://github.com/quinnj/Rosetta-Julia. I started it when I first got involved with julia and it's got a fair number of examples and exercises.

-Jacob

Alireza Nejati

unread,
Jun 23, 2014, 6:08:08 PM6/23/14
to julia...@googlegroups.com
Actually, a slight modification. The way I wrote it, it will compute the product of all matrices with all vectors (pxp mults), which is not what you want. You just want each matrix to multiply its respective vector (p mults). The solution to that is:

p = length(matlist)
reduce(+, [matlist[i]*veclist[i] for i = 1:p])


On Monday, June 23, 2014 2:43:32 AM UTC+12, Michiaki Ariga wrote:

Aerlinger

unread,
Jun 23, 2014, 7:35:38 PM6/23/14
to julia...@googlegroups.com
Very cool! Would be interesting to see some examples that utilize the functional aspects of the Julia language.

Michiaki Ariga

unread,
Jun 26, 2014, 9:54:34 AM6/26/14
to julia...@googlegroups.com
In original numpy version as following, matrix and vector are 3dimension arrays.
Is there any way to compute tensordot like numpy?

p, n = 10, 20
M = np.ones((p,n,n))
V = np.ones((p,n,1))
S = np.tensordot(M, V, axes=[[0, 2], [0, 1]])
print S
# returns 
#[[ 15.]
# [ 15.]
# [ 15.]
# [ 15.]
# [ 15.]]

2014年6月24日火曜日 7時08分08秒 UTC+9 Alireza Nejati:

Steven G. Johnson

unread,
Jun 26, 2014, 4:59:15 PM6/26/14
to julia...@googlegroups.com


On Thursday, June 26, 2014 9:54:34 AM UTC-4, Michiaki Ariga wrote:
In original numpy version as following, matrix and vector are 3dimension arrays.
Is there any way to compute tensordot like numpy?

There is no built-in tensor contraction function at the moment (https://github.com/JuliaLang/julia/issues/3250), but you can try out the TensorOperations package:


You can also just write your own loop and the performance should be fine; it's pretty easy to do this if you know the dimensionality in advance, and it's only complicated to write tensor contraction code if you want to handle arbitrary dimensionality and arbitrary contraction index sets.  (It takes a while to get used to the fact that you don't need to call a library function for every inner loop in Julia.)

Michiaki Ariga

unread,
Jun 27, 2014, 11:28:02 AM6/27/14
to julia...@googlegroups.com
I solved Expert 4 by Alireza's approach like following. (I don't understand how to use TensorOperations.jl in this case)
Thanks for Alireza!

```
p, n = 10, 20
M = ones(n,n,p)
V = ones(n,p)
S = reduce(+, [M[i,:,j]*V[i] for i = 1:n, j = 1:p])'
S
```

2014年6月27日金曜日 5時59分15秒 UTC+9 Steven G. Johnson:

james.dill...@gmail.com

unread,
Jul 5, 2014, 6:13:01 PM7/5/14
to julia...@googlegroups.com
In Apprentice.2, I think there is a minor typo in your solution.

R = sqrt(X'*X + Y'*Y)
is a scalar. 

I *think* a reasonable solution is:

Z = rand(100,2)
Y = zeros(100,2)    
for i = 1:100
    Y[i,1] = norm(Z[i,:],2)
    Y[i,2] = atan2(Z[i,2],Z[i,1])
end    

or its equivalent as a comprehension.

Jim
Message has been deleted

james.dill...@gmail.com

unread,
Jul 5, 2014, 9:01:46 PM7/5/14
to julia...@googlegroups.com

In Apprentice.6,  I don't think you want to use the sqrtm().  sqrt() is already vectorized over the matrix.  Also a couple of '.'s are misplaced, so perhaps instead:

Z =rand(10,2)

D = sqrt((Z[:,1].-Z[:,1]').^2+(Z[:,2].-Z[:,2]').^2)

As a newbie myself, what surprised me is that this is faster and allocates less memory than the comprehension:

D =  [norm(Z[i,:]-Z[j,:],2) for i = 1:10, j = 1:10]

I am sure someone else here can explain why.

Jim
On Sunday, June 22, 2014 10:43:32 AM UTC-4, Michiaki Ariga wrote:

Michael Prentiss

unread,
Jul 5, 2014, 9:58:06 PM7/5/14
to julia...@googlegroups.com
Julia is not as performant with anonymous functions, and list comprehension.   
The compiler has a harder time with the optimization step.  This is not a surprise and is
known to the language designers.  This is not a surprise.

Michiaki ARIGA

unread,
Jul 6, 2014, 9:23:14 AM7/6/14
to julia...@googlegroups.com
Thank you for your correction, Jim.

In Apprentice.2, same approach with numpy version, I fixed as following.

```
Z = rand(100,2)
X, Y = Z[:,1], Z[:,2]
R = sqrt(X.^2 + Y.^2)
T = atan2(Y,X)
```

Also in Apprentice. 7, I fixed . position.

I understand Julia works well without anonymous function, so when should I use array comprehension?
Do I have to make function to use array comprehension?

Many people advised to use array comprehension in this thread, but I don't understand when to use it...

John Myles White

unread,
Jul 6, 2014, 11:49:27 AM7/6/14
to julia...@googlegroups.com
I think anonymous function usage and list comprehensions are separate issues.

Anonymous functions are not type-specialized, so they’re basically always slow. I avoid them in any code that’s not one-off.

List comprehensions are type-specialized, but the inference for them isn’t super robust, especially in the global scope. There’s a couple of points of uncertainty: (1) how long will the result be?, (2) what’s the return type of the expression being evaluated in the comprehension, (3) does anything in the comprehension mutate anything? If you use typed list comprehensions, you can work around (2), but (1) and (3) are still potentially issues. That said, array comprehensions aren’t a lot slower than explicit loops, so many people like them — especially people coming from Python, where they’re very popular.

 — John
Reply all
Reply to author
Forward
0 new messages