NYCJUG/2008-01-08
trees in APL and J, placing text on a plot, evening out plot of a function, Excel add-ins in J, graphics capability
Agenda
Meeting Agenda for NYC JUG 20080108 ----------------------------------- 1. Beginner's regatta: tacit for beginners - considered harmful versus explicit adverb notation? 2. Show-and-tell: a suggestion for a tree class (from parseDir.ijs). Placing text on a plot. Evening output of a function. 3. Advanced topics: How best to do Excel add-ins? Make a kit for this? See SampleSpreadsheetAddins.doc. 4. Learning and teaching J: perception of J graphics capability.
Beginner's Regatta
Tacit considered harmful? Some of us find explicit notation more natural and easier to comprehend than tacit notation. Tacit does offer advantages in efficiency of execution and avoids a certain amount of repetition in writing expressions as well.
Show and Tell
Trees
Placing Text on a Plot
In response to a question about how to place text on a plot next to chosen points, I came up with the following; the e-mail inquiry that prompted this, and my replies, are included with the code as nouns (using 0 : 0 ).
Intro=: 0 : 0 from June Kim <juneaftn@gmail.com> 4/9/06 reply-to Programming forum <programming@jsoftware.com> to Programming forum <programming@jsoftware.com> date Apr 9, 2006 4:25 AM subject [Jprogramming] labeling on points in plot Hello. Say, I have a simple plot: load 'plot' plot 0 1 2 3;1 2 3 5 I'd like to label on some data points. For example, the second data point (1,2) should be labeled as "foo" on the plot view, and the third point (2,3) as "bar" on the view. (It would be better if the data point is marked, too) Is there a convenient and easy way of doing this in general cases? June ) MySecondReply=: 0 : 0 from Devon McCormick <devonmcc@gmail.com> 1:11 pm (8 minutes ago) reply-to devon@acm.org to Programming forum <programming@jsoftware.com> date Dec 26, 2007 1:11 PM subject Re: [Jprogramming] Re: labeling on points in plot I realized my code was insufficiently general because it labels only the highest and lowest points, so here's an example of labelling a randomly-chosen point. The magic values of "1000" are based on my understanding that the virtual size of the plot area is 1000x1000 "characters". ) lblRnd=: 3 : 0 pd 'reset' rr=. _100+20?201 NB. Random points to plot whrp=. ?#rr NB. Location of a point at random. rp=. whrp{rr NB. Value of the random point xrnd=. ":<.0.5+1000*(#rr)%~whrp NB. Estimate x-position of random pt. span=. (>./-<./)rr yrnd=. ":<.0.5+1000*(rp-<./rr)%span NB. Estimate y-position of random pt. NB. Place text for random point: pd 'textfont Courier 12 Bold;textcolor BLACK' pd 'text ',xrnd,' ',yrnd,' Val=',":rp pd 'pensize 5;type point' pd <"1 rr,:~i.#rr pd 'show' ) NB.EG pts=. 1 o. 8%~i:49 labelPoints=: 3 : 0 pd 'reset' 'rpts p2l'=. y NB. Vector of points to plot, indexes of points to label. wh=. (<rpts) label1Pt&.>p2l pd 'pensize 5;type point' pd <"1 rpts,:~i.#rpts pd 'show' wh NB.EG labelPoints (1 o. 8%~i:49);0 11 36 62 87 98 NB. Label extrema ) LP=: 20 900 50 1400 10 NB.* label1Pt: allow parameter refinement to label points: use global LP: NB. x offset, scaling, y offset, scaling, font point size. label1Pt=: 4 : 0 'whrp rpts'=. y;<x rp=. whrp{rpts xrnd=. ":<.(0{LP)+(1{LP)*whrp%#rpts NB. Estimate plot-area x-position span=. >:(>./-<./)rpts yrnd=. ":<.(2{LP)+(3{LP)*(rp-<./rpts)%span NB. Est. plot-area y-position pd 'textfont Courier ',(":4{LP),' Bold;textcolor BLACK' pd 'text ',xrnd,' ',yrnd,' ',":rp xrnd,' ',yrnd )
Evening Out Plotted Points of a Function
I queried the J forum with the following:
from Devon McCormick <devonmcc@gmail.com> 12/27/07 reply-to devon@acm.org to J-programming forum <programming@jsoftware.com> date Dec 27, 2007 11:05 AM subject Evening output Members of the Forum: If I plot the points of a sine curve thusly 'type point;pensize 5' plot 1 o. 8%~i:49 I get a nice graph but, due the nature of the sine function, points near the inflection points are more closely spaced than those further away. How can I adjust my input points to get more evenly-spaced (for simplicity, on the Y-axis) outputs? I'd like a method I could use for any arbitrary function. Here's a simple attempt wherein I try to remove the point closest to the one before it and insert a point midway between the two most widely separated points: NB.* evenOut: adjust inputs to fnc so outputs more evenly spaced. evenOut=: 1 : 0 diffs=. |2-~/\u y 'whi wlo'=. diffs i. (>./,<./)diffs wlo=. wlo-wlo=<:#y NB. Don't remove endpoint y=. (0 (>:whi)}1$~>:#y)#^:_1 y y=. (u -:+/y{~whi+0 2) (>:whi)}y y=. (<<<>:wlo){y ) evenOut_test_=: 3 : 0 tsts=. 0 1 10,0 10 11,:0 5 10 assert. (] evenOut"1 tsts)-:(5.5 5 5) 1}&.|:tsts ) If I could get a satisfactory version of this two-point substituter, it might work to apply it repeatedly until the point differences stabilize. I'm satisfied with the result for these simple test cases: ]tsts=. 0 1 10,0 10 11,:0 5 10 0 1 10 0 10 11 0 5 10 ] evenOut"1 tsts 0 5.5 10 0 5 11 0 5 10 (Testing with verb "]" for simplicity). However, this result ] evenOut 0 2 4 5 0 1 2 5 isn't as good; a result like "0 2 3 5" might be better in this case. We could define a measure of evenness: msrEveness=: 13 : '%:+/*:2-/\|2-/\y' to quantify this preference (where a lower measure is better). This shows us that of the three possibilities, msrEveness ] evenOut 0 2 4 5 2 msrEveness 0 2 4 5 1 msrEveness 0 2 3 5 1.4142136 the initial arrangement is best. An arrangement like this msrEveness 0 5r3 10r3 5 0 is optimal in this case (we want to retain the endpoints unchanged). Any ideas on how to approach this?
After some mis-communications and dead-ends, Raul Miller made the following helpful suggestion:
from [[User:Raul Miller|Raul Miller]] <rauldmiller@gmail.com> 12/27/07 reply-to Programming forum <programming@jsoftware.com> to Programming forum <programming@jsoftware.com> date Dec 27, 2007 4:41 PM subject Re: [Jprogramming] Re: Evening output On 12/27/07, Devon McCormick <devonmcc@gmail.com> wrote: > Well, something like > 1 o. _1 o. 8%~i:49 > just gives me a straight line. I see two problems here. First, if you want variable x, you need to include your x axis values in the data you send to plot. Second, the domain of _1&o. lies between _1 and 1 Try: plot (;1&o.) _1 o. 8%~i:49 > In any case, I'm looking for a solution to evenly space the results > of any function - sine is only an example function. I think this amounts to solving for k=((dx%dt)^2)+(dy%dt)^2) for some arbitrary function y of x so you can find the arbitrary function x of t. Instead of trying to approach this directly, I might try generating lots of extra points, and then finding the distance between each point and then doing a sum scan on them and then using I. to find points roughly separated by an even interval and using those indices to select from your original surplus of points. (That said, I have not tested this approach -- and note that ill-behaved functions could still have unevenly spaced points, or other such issues.)
This last suggestion led me to work out the following:
egConverge=: 0 : 0 pts0=: /:~_6.125 6.125 scaleNums ?5000$0 cumdif=. 0,+/\|2-~/\1 o. pts0 msrEveness 1 o. pts0{~ixs=. linkChain 0;cumdif;0.125 0.21224104 msrEveness 1 o. pts0{~ixs=. linkChain 20;cumdif;0.125 0.32405618 msrEveness 1 o. pts0{~ixs=. linkChain 10;cumdif;0.125 0.32287861 msrEveness 1 o. pts0{~ixs=. linkChain 40;cumdif;0.125 ) improveEvenness=: 1 : 0 inppts=. y svpts=. u fuzzAlt inppts msrs=. (_10 msrEveness\1 o. inppts)>:_10 msrEveness\1 o. svpts newpts=. ;{."1 msrs|."(0 1)(_10<\inppts),._10<\svpts ) msrEveness=: 13 : '%:+/*:2-/\|2-/\y' linkChain=: 3 : 0 NB. starting index, vector of ascending values, target difference 'ix vav targ'=. y elm=. ix{vav ixs=. ix while. ix<<:#vav do. NB. Find where closest to target diff. ix=. (>:ix)([+[:(]i.<./)}.)|vav-elm+targ elm=. ix{vav ixs=. ixs,ix end. ) egWorkout1=: 0 : 0 'grpsz targ'=: 20 0.125 pts0=: (8*100)%~i:49*100 cumdif=. 0,+/\|2-~/\1 o. pts0 msrEveness 1 o. pts0{~ixs=. linkChain 0;cumdif;0.125 NB. 0...n -> local minimum, then look plarg plot (;1&o.)pts0{~0,ixs NB. and further: 10{.ixs 78 183 295 417 556 731 1193 1539 1712 1850 2-~/\10{.ixs 105 112 122 139 175 462 346 173 138 NB. So look for a second group around the midpoint: msrEveness 1 o. pts0{~ixs2=. linkChain 250;cumdif;0.125 0.28432567 msrEveness 1 o. pts0{~ixs2=. linkChain 260;cumdif;0.125 0.2378087 NB. ... msrEveness 1 o. pts0{~ixs2=. linkChain 290;cumdif;0.125 0.036468168 msrEveness 1 o. pts0{~ixs2=. linkChain 300;cumdif;0.125 0.060224223 NB. ... msrEveness 1 o. pts0{~ixs2=. linkChain 294;cumdif;0.125 0.031203234 NB. Compare the two: plarg plot ((;1&o.)ixs{pts0),:&.>(;1&o.)ixs2{pts0 plarg plot ((;1&o.)pts0{~0,ixs),:&.>(;1&o.)pts0{~0,ixs2 NB. Compare (versus random initial): pts0=: /:~_6.125 6.125 scaleNums ?5000$0 cumdif=. 0,+/\|2-~/\1 o. pts0 msrEveness 1 o. pts0{~ixs=. linkChain 0;cumdif;0.125 0.21224104 NB. ... msrEveness 1 o. pts0{~ixs=. linkChain 38;cumdif;0.125 0.069860846 msrEveness 1 o. pts0{~ixs=. linkChain 37;cumdif;0.125 0.070036823 msrEveness 1 o. pts0{~ixs=. linkChain 39;cumdif;0.125 0.070104338 31%6.125 5.0612245 $pts2=. 5.0612245%~i:31 63 plarg plot ((;1&o.)pts0{~0,ixs),:&.>(;1&o.)pts2 msrEveness 1 o. pts2 0.20572114 msrEveness 1 o. pts0{~0,ixs 0.075403243 NB. Statistically, the two are very similar: usus pts0{~0,ixs _6.125 6.125 0.0080577311 3.655643 usus pts2 _6.125 6.125 2.2556912e_16 3.621713 NB. So is randomly started: cumdif=. 0,+/\|2-~/\1 o. ptsr=: /:~_6.125 6.125 scaleNums ?5000$0 msrEveness 1 o. ptsr{~ixsr=. linkChain 35;cumdif;0.125 0.056135369 $ixsr 62 msrEveness 1 o. ptsr{~0,ixsr 0.05835126 usus ptsr{~0,ixsr _6.125 6.125 0.0054441791 3.6309849 ) NB.* chTh1: find longest chain through candidates chTh1=: 3 : 0 'ix mat'=. y NB. 2-row mat ixs=. ix elm=. (<0,ix){mat 'lower hier'=. mat while. lower e.~ elm=. ix{hier do. ix=. lower i. elm ixs=. ixs,ix end. ixs ) ppts=. ((pts0{~ixs2);1 o. pts0{~ixs2),:&.>(i:6.125j62);1 o. i:6.125j62 ppts=. (<0 0.1+"(0 1)>0{ppts) 0}ppts NB. Offset original a little over ppts=. (<0 0.05+"(0 1)>1{ppts) 1}ppts NB. and up. plarg=. 'title Sine Wave Evened Out;pensize 5;type marker;' plarg=. plarg,keystyle m;keypos lcr;key Evened "Original (offset)"' plarg plot ppts pd 'save png C:\amisc\j\nycjug\200801\evenedOutVsNot.png' 4477368
Which results in the following picture. The red points are the original ones (offset slightly to avoid overlap); notice how they are close together at the turning points (the tips of the peaks and bottom of the valleys). The blue ones are more evenly spaced, which is the point of the exercise.