Le mercredi 21 mai 2014 14:55:34 UTC+2, Tim Holy a écrit :
>
> I agree that vectorizing is very nice in some circumstances, and it will 
> be 
> great if Julia can get to the point of not introducing so many 
> temporaries. 
> (Like Tobi, I am not convinced this is an easy problem to solve.) 
>
> But there are plenty of cases where loops are clearer even when 
> vectorization 
> is both possible and efficient. For example, surely you can't tell me that 
>
>     L = similar(A) 
>     m,n = size(A) 
>     L[2:m-1,2:n-1] = A[3:m,2:n-1] + A[1:m-2,2:n-1] + A[2:m-1,3:n] + 
> A[2:m-1,1:n-2] - 4A[2:m-1, 2:n-1] 
>
> is easier to read and understand than 
>
>     L = similar(A) 
>     for j=2:size(A,2)-1, i=2:size(A,1)-1 
>         L[i,j] = A[i+1,j] + A[i-1,j] + A[i,j+1] + A[i,j-1] - 4A[i,j] 
>     end 
>
> I completely agree. When I was talking about vectorized code, I meant what 
Andreas showed.

 

> Not only does the loops-version have fewer keystrokes, it's a heck of a 
> lot 
> clearer that what you're doing is computing the 2d discrete laplacian. 
>
> --Tim 
>
> On Wednesday, May 21, 2014 05:09:57 AM Andreas Lobinger wrote: 
> > Hello colleague, 
> > 
> > On Wednesday, May 21, 2014 7:33:01 AM UTC+2, Andreas Noack Jensen wrote: 
> > > Please consider b += Diagonal(c) instead of diagm. Diagonal(c) only 
> stores 
> > > the diagonal elements but works like diagm(c) for matrix arithmetic 
> > > 
> > > Vectorized code is always easier to understand 
> > > 
> > > 
> > > That is a strong statement. I have vectorised MATLAB code with repmat 
> and 
> > > meshgrids that is completely unreadable, but would be fairly easy to 
> > > follow 
> > > if written as loops. I really enjoy that I can just write a loop in 
> Julia 
> > > without slow execution. 
>
Me too :)  I agree about my statement: I completely overlooked complicated 
slicing and stuff. But I also said that a part of what made explicit loops 
less easier to understand are explicit indices. Same thing goes for 
"vectorized" code.

My whole point is to say that, in general, one should divide the problem 
into understandable pieces to write clear code. Vectorized expression are a 
way to get that. For instance,

A -= Diagonal(B)

is very easy to understand, if not obvious. You almost wrote in plain 
english there, and that's a strength: no need to *actually* understand the 
code to grasp what it does.

for i=1:length(B)
    A[i, i] -= B[i]
end
is not that hard to understand because it's really short, but there, the 
only way you can get the intent of the programmer is by browsing the whole 
code and understanding the whole thing.

To get back to Tim example.
On could think of creating a DiscreteLaplacian2D function taking a matrix A 
as an input. This is actually what I would do to keep the complexity of any 
given piece of code very low. Let's solve the heat equation iteratively, 
for that we need to calculate:

DiscreteDerivative(A, 1) - alpha.*DiscreteLaplacian2D(A, [2,3])

or even better, knowing the shape of A:

TimeDerivative(A) - alpha.*SpaceLaplacian2D(A)

are very easy to grasp and understand. I've not directly used loops : this 
is plain vectorized code. It's obvious and easy to maintain.

I'm sure you will agree. But what's the problem then? This is not *really*what 
you meant about vectorized code.

Well, let's handle the same problem with the current trend : this is not as 
fast as Julia could, this might be fast enough but definitely not the 
fastest. It's also using more RAM that it should, so why not *rewriting it 
into loops*? Yes, of course, why not! The only problem is that the only way 
to achieve something usefull would be to solve the *whole* equation in one 
fat bunch of loops. Which means:

   - Duplicated code all over the place. You'll have to write/(copy/paste) 
   your devectorized laplacian for *each* single equation that needs it.
   - Unreadable code.
   - Longer code.
   - More places to make mistakes.
   - More places to search for to correct copy/paste mistakes.
   - Bigger mental map for you project.
   - Fewer external contributors.
   - more "end"s ;)
   

> 
> > If you write code in Matlab (or similar) that's using repmat (nowadays 
> > bsxfun) and meshgrids (and reshape) you are operating on wrong side of 
> > vectorising your code. Most likely (and there might be good reasons for 
> > that) your data is not in the 'right' shape, so you reorder more than 
> you 
> > calculate. For problems like this explicit loops are often the better 
> way 
> > (so straightforward in julia) OR you take some thinking, why the data 
> needs 
> > to be reordered for certain operations. 
> > 
> > The right side of vectorized code is the SIMD thinking which does 
> > operations (some times linalg) on Matrix/Vector forms, and that in the 
> best 
> > sense leads to one-liners like 
> > 
> > M += ((A*B) + (d*C) + (E .* M0)) 
> > 
> > which are easy to read/write/understand. 
> > 
> > Expressions like this seems to create in julia an incredible ammount of 
> > intermediates and temporary allocations, while actually the output array 
> > (M) is already allocated and the + and * operations just needed to be 
> > executed with the 'right' indexing. 
> > 
> > Some people tend to solve this by writing explicit loops and create half 
> a 
> > page of code for the above one-liner. 
>

Reply via email to