This is, of course, great. Thank you and I'll try to incorporate most of it.
I noticed that the links in my gmail copy of this post worked, but those with trailing periods in the archive don't because the link there somehow incorporates the period. --Th On Wed, Apr 18, 2018 at 6:16 PM, Marshall Lochbaum <[email protected]> wrote: > This is a perfectly good use of the forums in my book. At the very > least, we've had similar posts before and no one's complained. > > Overall your program looks pretty good to me. It's not leveraging the > Full Power of J™, but it's a great start. You know what I. does! > > There are some ways to use arrays to do more of your work for you. You > write > > 'minCut maxCut' =. x > ... > minWanted =: (<.minCut*#srtData){srtData > maxWanted =: (<.maxCut*#srtData){srtData > > but this is the same as > > 'minWanted maxWanted' =: (<.x*#srtData){srtData > > since each of * <. and { has rank zero, that is, maps over arrays, on > the side of x. (Unrelatedly, these should probably use =. rather than =: > to avoid global assignment. It looks like they might have been =: for > debugging, but if so, it's good practice to look over the code again and > change them back when you're done.) > > A more sophisticated example is the plane-scaling code in displayFits. > You use different code for each different number of scalings to do: > > r =. minmax scaleT2D 0{imarray > select. 3<.{.$imarray NB. use up to 3 planes > case. 3 do. > g =. minmax scaleT2D 1{imarray > b =. minmax scaleT2D 2{imarray > case. 2 do. > b =. minmax scaleT2D 1{imarray > g =. -: r+b NB. average of red and blue > case. 1 do. > 'g b'=. r;r > end. > > Instead, you could do all the scalings in one go: > ((#imarray) is like ({.$imarray), but it is a scalar and not a vector.) > > numScales =. 3<.#imarray NB. use up to 3 planes > scaled =. minmax scaleT2D"_ _1 numScales {. imarray > if. numScales < 3 do. > avg =. (+/ % #) scaled > scaled =. scaled , (3-numScales)#,:avg > end. > 'r g b' =. scaled > > This example first uses scaleT2D with an explicit rank to operate on > each of the first numScales planes. If you're not familiar with it, my > favorite explanation of the rank conjunction (") is > http://www.jsoftware.com/help/jforc/loopless_code_i_verbs_have_r.htm. > A rank of (_ _1), that is, infinity on the left and minus one on the > right, means to apply the function to the entire left argument and each > subarray of the right argument, effectively mapping over only the right > argument. I could have used a rank of 2 rather than _1 on the right, but > rank _1 is more flexible--it would work even if the planes were instead > three-dimensional. > > After this compuation, scaled is a three-dimensional array of the first > numScales planes of imarray. The average of its planes can be found with > the standard averaging function (+/ % #), which happens to be the > canonical example of a fork. If you're interested, these are described > at http://code.jsoftware.com/wiki/Vocabulary/fork. > > An exponent like (2^8) unfortunately always evaluates to a > floating-point number. I habitually use (<.@^) when I know the arguments > are integers to avoid accidentally promoting to floats. > > > I actually gave a talk on a task similar to the parsing you do here. My > task was to parse the header of a simple wave file. A script version > (there's no recording that I'm aware of) is at > http://code.jsoftware.com/wiki/Community/Conference2014/ > Talks/UsingDataAsCode > and the current script that I use based on this is > https://github.com/mlochbaum/JSound/blob/master/wav.ijs. > This is certainly difficult material for a beginning J programmer, but > the techniques discussed in the talk might be useful for you as you gain > more skill. > > One neat trick similar to the one used there: rather than write > > bitpix =. hdata getHdrVal 'BITPIX' > naxis =. hdata getHdrVal 'NAXIS' > naxis1 =. hdata getHdrVal 'NAXIS1' > naxis2 =. hdata getHdrVal 'NAXIS2' > naxis3 =. hdata getHdrVal 'NAXIS3' > > you might use > > fields =. ;: 'BITPIX NAXIS NAXIS1 NAXIS2 NAXIS3' > (fields) =. hdata&getHdrVal&.> fields > > and then the fields will be defined in variables BITPIX, etc. > > Another very cool trick that I found after the talk would be useful > here: > > select. bitpix > case. _32 do. adata =. (naxis3,naxis2,naxis1)$ |. _1 fc |. rdata > case. _64 do. adata =. (naxis3,naxis2,naxis1)$ |. _2 fc |. rdata > case. 16 do. adata =. (naxis3,naxis2,naxis1)$ |. _1 ic |. rdata > case. 32 do. adata =. (naxis3,naxis2,naxis1)$ |. _2 ic |. rdata > end. > > The idea is to make an adverb (mine is audioconvert in wav.ijs) which > takes a format specification like bitpix and returns a conversion > function. Something like: > > rawconvert =: 1 : 0 > select. u > case. _32 do. _1&fc > case. _64 do. _2&fc > case. 16 do. _1&ic > case. 32 do. _2&ic > case. do. 'Invalid format' assert 0 > end. > ) > > which can then be called with > > cvt =. bitpix rawconvert NB. A conversion function > adata =. (naxis3,naxis2,naxis1)$ |. cvt |. rdata > > Now the really cool thing is that J knows how to invert each of these > functions. So when you want to store the data again, you just use > (cvt^:_1)! This is a J-only technique: I don't know of any other > language that has the functional capabilities and the automatic > inversion required to do it. > > There's always more to say but I think that's enough for one email. Good > luck with your future J projects! > > Marshall > > On Wed, Apr 18, 2018 at 02:47:02PM -0400, Thomas Hickey wrote: > > As one of my first J programs, I've written a minimal viewer for FITS > > files, the standard way of sharing astronomical data, especially images. > > > > I'd appreciate it if someone could take a look at it and let me know how > > the code (80 lines of J) looks. I know I've replaced some really awkward > > code in it, so I imagine there are better ways of doing lots of things. > > > > The code is on GitHub at https://github.com/ThomasBHickey/JFits, along > > with a sample FITS file in the fitsSample folder. Pointers on > organizing J > > code on GitHub would be appreciated as well. > > > > Or is there a better way to accomplish this than the programming forum? > I > > know this is longer than most of the questions that are posted here, but > I > > think it is an interesting application of J. > > > > --Th > > ---------------------------------------------------------------------- > > For information about J forums see http://www.jsoftware.com/forums.htm > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
