trees in APL and J, placing text on a plot, evening out plot of a function, Excel add-ins in J, graphics capability
Contents
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 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'
4477368Which 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.
Advanced Topics: Excel Add-ins
Learning and Teaching J
Scan of Meeting Notes
