Random walk in 2 lines of J
asindu.xyz
asindu.xyz
Rand ← -⟜¬ •rand.Range⟜0
•Plot {+` 𝕩 ↑ ⥊∘⍉∘≍´⌽ -⟜«∘Rand¨ (1⌈↕∘⌈)⌾(2⋆⁼⊢)2⌈𝕩} 500
A slightly spread out translation of the function to J below. The idea is to take lengths 2 2 4 8 16... up to the required length, and then repeatedly interleave the two smallest ones to get a fractal pattern. The interleaved values are differences of white noise, and a final sum undoes these differences to leave a sum of white noise at several different frequencies. pink =: {{
len =. (1>.i.@>.)&.:(2&^.) 2>.y
diffs =. (2-~/\0,[:(--.)?@$&0)&.> len
+/\ y {. >,@,.&.>/|. diffs
}}
Adapted from [0], which I was able to simplify some when I ported it from an earlier J version [1]. I think having the whole algorithm there at once was definitely helpful in figuring out what I meant to do and writing it more cleanly.[0] https://github.com/mlochbaum/BQNoise/blob/master/tracker.bqn...
[1] https://github.com/mlochbaum/JSound/blob/master/makedrums.ij...
plot+/\_1+2*?100#2What an awful looking language. Laughing my ass off.
from matplotlib import pyplot as plt
import numpy as np
plt.plot(np.cumsum(np.random.choice([-1,1], 100)))The cost of doing something extra is much lower in J/APL than other more verbose languages just because of how easy it is to type a few characters and get a result - this combined with a repl and similar things makes it really nice for exploration.
walks = np.random.choice([-1,1], (100, 1000))
running_sum = np.cumsum(walks, axis=0)
plt.plot(running_sum)
Intuitively it seems like the more complicated the problem, the bigger the advantage for a language like numpy where functions are used for most higher level abstractions. For example what if you want to change the logic to do a stopped game, where you now keep each walk at zero once it becomes zero, and count the portion of walks that stop after some fixed duration? In numpy I can always fall back to list comprehensions or for loops for something like that. Is it easy to express logic like this in J?The modification you mentioned is straightforward in any array language. Here is what you mentioned in APL (I know APL more than J but I'm sure the J would be basically the same):
⊃⍤⍸⍤1⊢0=+\¯1*?100 1000⍴2
This is the number of steps to return to 0 for each of 100 random walks of length 1000. (It is then easy to analyse the frequency/average/etc with only a few more characters) 1 + np.min(np.argwhere(running_sum[1:] == 0), axis=0)IMHO the APL-family languages are precisely good at things like this, where there's lots of "array processing" going on; on the other hand, typical branchy business logic or other more "mundane" algorithms tend to be a bit harder to express.
I wonder if APL-like languages (or their variants with more verbose syntax, like numpy) make any inroads in that space.
[1]: https://futhark-lang.org/blog/2016-06-20-futhark-as-an-apl-c...
Does it actually succeed though? The author aims to show how J helps conceptualize a random walk, but from where I stand, it just makes everything look like a regex or something. I don't see what the insight's supposed to be.
Everybody knows you can do a random walk by simulating an array of random 1 and -1 values and doing a cumsum on that array. You can do that in MATLAB or Python or R too, and it's about as short and more readable.
Not sure about J, but I feel APL certainly does, at least for me - the symbol set makes it very easy to sketch out a solution.
Part of that ease is the generality of the various operators. That is the reductions and cumulative prefix can be done with any function. For example ⌊\ as cumulative min - useful as Vanessa McHale shows <http://blog.vmchale.com/article/numba-why>
kspalaiologos also shows APL enabling mathematical understanding on her blog <https://palaiologos.rocks/>
An APL equivalent of the J is +\¯1 1[(?100⍴2)] although others exist as there's no exact equivalent for J's { - see <https://aplwiki.com/wiki/From>
> One misconception is that languages like J are in the same caliber as less practical languages (esoteric languages like brainf*k) that use symbols more than words. The assumption is that these are mostly for recreational programming.
Making some crude assumptions here, I believe you've already invested a lot of time into studying python, or some other well known language. Understanding python or C gives you an idea of hundreds of other languages because they use similar keywords and structures to represent their code. English also helps a great deal in understanding these languages.
Now, looking at this, giving a language like APL or J a chance means that you have to spend time learning their kind of notation. If you spend your time looking at APL without making an effort to understand it, then you cannot be surprised that it looks like regex to you.
For example, say I want to the digits of 1000!
echo '!1000' | j9 -c gives '_' which is the greatest number.
echo '!1000x' | j9 -c gives some of the digits. | rev, gives ...8393650(...)
echo '(9!:37) 0 _ 0 1 \n !1000x' | j9 -c gives all the digits. | rev, gives 0000000(...)
echo '!1000' | ivy works as expected, but has a noticeable startup time.
Of course, J and only J works just fine internally with the second form.
On the subject of modules: Don't. If your plot program is so great then I want to use it, outside J. If its main feature is interoperability with an operability-hamstrung language, then to quote another commenter, "Pass".
At core, my job is arithmetic on 3D arrays of approx 10x1000x100,000,000.
The rub is that for every LOC of written manipulating those structures I’ve got 100 LOCs doing IO (broadly defined) and then 1,000-10,000 doing some form of ETL, QC, normalization (I.e. find and validate the correctness of the magic numbers that go in the cells of the big array).
Do you think J/APL would be of any use to me and if so where in your similar projects’ life cycle does it crop up?
At the time my own answers in C would take dozens or even hundred of lines. I didn't know J existed and thought people posting those absurdly small solutions were just trolling or running a scam.
Man was I left dumbfounded when I learned this thing actually runs and produces the correct answers.
For the lesser-gifted like myself, I wonder if one couldn't attain the power of J without the cryptic syntax. Haskell, for example, has a general very easily understood syntax for function applications: if "add a b" invokes a binary add function than "add a" is a unary function that adds a and the syntax allows for infix expressions, like "a `add` b", "(a `add`)", and (`add` b). (The latter more useful for non-alphanumerically named functions, like (++ [42]). I wonder if J/Apl couldn't use a similar strategy to trade a bit of terseness for something much more readable.
It probably won't teach effectively more complex features, you might need a bigger project for that. But it will add to familiarity. Where other languages have lots of libraries, J has language where many things are just so easy to assemble from few language primitives.