6 ms·
having used both FORTRAN and Julia, Julia generally had less friction and comparable speed. JIT is great for having a very short programming loop. I definitely
by waveBidder 3y ago
having used both FORTRAN and Julia, Julia generally had less friction and comparable speed. JIT is great for having a very short programming loop. I definitely prefer Fortran to Python though for math programming.
- noobermin 3y agoThe insistence of using dot operators for nonsensical purity ruined julia for me. A good example of computer scientists ruining things.
- kstrauser 3y agoCan you give an example? I haven’t used Julia and I’m curious to hear what you mean by that.
- porridgeraisin 3y agoNormally, languages implement SIMD compilation for a specific set of data types/structures and even then you have to really make sure to ask the compiler nicely. Julia is able to vectorize any generic, user-defined data types/operators/functions. This comes at the cost of pretty horrid syntax. It needs extra syntax to give the compiler the information, for sure, but you can argue that it could have been chosen better. X .= f.(2 .* X.^2 .+ 6 .* X.^3 .- sqrt.(X))
- kwertzzz 3y agoOr just use @. julia> X = [1.,2.,3.]; f=sin; julia> @. X = f(2 * X^2 + 6 * X^3 - sqrt(X))
- noobermin 3y agoIn fortran 90, an example I have sitting around: c_y = (qmr*ey_sub*dtsq + c_y*(2 - omsq_b*dtsq))/gmdto2p1 - c_ym1*gminv ey_sub, c_y, c_ym1 are N long arrays with the same shape, and in this case, the operation is elementwise, so indexing isn't needed, and I do not need an explicit do-loop (for loop in C languages) so it fits on a single line that is readable to a scientist in the field. The julia equivalent, I think is the same with a period on every operator c_y .= (qmr.*ey_sub.*dtsq .+ c_y.*(2 .- omsq_b.*dtsq))./gmdto2p1 .- c_ym1.*gminv The assignment was already verbose as it is, and I at the time tried to make it terser but still marginally readable by using variables that are named for...scientists I guess (e.g., gmdto2p1 means "gamma * dt / 2 + 1" dto2 thoughout the codes I read and use is "dt over 2") and adding 10 characters makes a little more cumbersome. While I think the visuals can be acclimated to, it is tedious to write, especially when you translate a formula from vectorised form to non vectorised or vice-versa and have to insert or delete periods. Mind you this is one of the simpler formulae in the code in question. You can imagine it quickly gets worse when the number of terms exceeds 6 or so. If you can't rely on implicit-do or terse assignment statements, then the good alternative in terms of readability then for the formula is just to do an explicit do-loop (for loop for julia). ! fortran 90, `integer i` above do i=1,size(c_y) c_y(i) = (qmr*ey_sub(i)*dtsq + c_y(i)*(2 - omsq_b*dtsq))/gmdto2p1 - c_ym1(i)*gminv end do # julia for i=1:length(c_y) c_y[i] = (qmr*ey_sub[i]*dtsq + c_y[i]*(2 - omsq_b*dtsq))/gmdto2p1 - c_ym1[i]*gminv end The problem is then I have made more extraneous bits to worry about. This gets even more hard to parse when the shape of the arrays exceeds more than 3 dimensions. I've read C style codes that are 7 levels deep with different indices, god is it painfully unclear and easy to get lost reading that, it's best to hide extraneous loops with syntactical sugar where possible such as to keep the algorithm as clear as possible, especially when it's a simple elementwise operation. It isn't like you can hide complexity all the time (or that it's even a good idea to do so), but this was a code for just two figures in a paper that needed a bit more oomf than numpy could, so given the time constraint for me, the size of the problem and everything, fortran fit much better. If you want to know more about the dot macro in julia, here is a nice blogpost about them[0]. The line above is from work I did for a paper that I initially thought "hey, it's been a few years, why not see if julia has stabilised by now" only to find out this was a decisive change they made. I mean they might deserve praise having made this macro a very general thing and apply widely to things that aren't just syntactical sugar for broadcasting, but after being frustrated trying to write my code, googling, and then finding this post, I basically dropped the julia learning effort and got the code written in fortran and made my figures. I can learn things in my spare time to a limit but at the end of the day I have a job to do. I still want to give julia a chance because the idea does seem cool. I complain about computer scientists a little tongue-in-cheek but really I find the metaprogramming in julia pretty interesting. I'm just not sure I can use it in my day job as a scientist without some effort in learning and time on my part which is at a premium right now. [0] https://julialang.org/blog/2017/01/moredots/ https://julialang.org/blog/2017/01/moredots/
- kwertzzz 3y agoIt took me awhile to get used to the dot operator, but what convinced me that it was a good choice is that also your own function can be broadcasted with function_names.(args). For example is you have a function process_a_file(in_filename,out_filename,parameter_value), then you can easily process also a list of files with process_a_file.(in_filenames,out_filenames,parameter_value) (if parameter_value is a scalar it gets broadcasted). I think that it is similar to numpy ufunc's but every function have this possibility. A useful macro is @. which allows you to write "@. A * B * C" instead of "A .* B .* C". Also the macro avoid the creation of an intermediate vector with A times B.
- sundarurfriend 3y agoI'm far from a computer scientist, and used to be a fan of "Do What I Mean" (DWIM) magic like automatic elementwise broadcasting. But have come to highly favour consistency and predictability over that with experience. I've certainly had moments where I've gone "just do that elementwise already, it's obvious!" and been mildly annoyed, but I'll take that any day over silent misbehaviour, hard to detect bugs, and being unable to tell at a glance what exact operations are going on in a line of code.
- cycomanic 3y agoBut I I would argue that for mathematical operations doing elementwise by default is much more consistent than doing matrix multiplication everywhere. Now the multiplication operator works differently (and importantly changes the shape of your result) based on what your arguments are. While elementwise behaves essentially like it was scalars everywhere. But the worst part of the elementwise operator is that they followed matlab and chose the freaking dot, the most easy to overlook character they could find. The issue is that missing the dot often does not result in errors but in bugs where somehow the code is not giving sensible results. Back in the days when I was still teaching matlab to students, the main source of bugs were missing dots which were always painful to find.
- waveBidder 3y agodo you mean f.(x) for broadcasting?
- eigenspace 3y agoWhat? That isn't at all about computer scientists. One of the most fundamental reasons for it is actually mathematical. Functions like exp and sin can be defined on numbers, but are also well defined on square matrices. In languages that have automatic broadcasting of functions across arrays, if you write exp(x) and x happens to be a matrix, you won't get the mathematically correct answer. You actually get [exp(xi) for xi in x] which is nonsense. Having the dot operators make it very easy to tell if a function should be operating on entire arrays or on elements of those arrays. It also enables performance enhancements, because if I write exp.(x) .+ 1 that will do [exp(xi) + 1 for xi in x] instead of [y + 1 for y in [exp(xi) for xi in x]] which wastes and allocation