| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| Hello, I'm working on a parametric (hermite, bezier, b-spline, etc) curve/surface/volume library as my first real piece of APL. I have a question about how to do a certain operation without loops. I need to construct a binomial coefficient and have written a function like this: n binc i (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i This works for things like 5 binc 2, which is 10. My question is: if i is a vector, so I might call the function like this: 5 binc 0 1 2 3 4 5 How can I get the response of a vector like 1 5 10 10 5 1 from binc? Do I need an explicit loop to iterate the operation across vector i {rho}i times? In scheme (for those who might know it), I could encapsulate binc into a higher order function, currying one of the arguments, and then map it across the vector i, like this: (map (lambda (x) (binc 5 x)) '(0 1 2 3 4 5)) But I don't know how to do a similar thing in APL without the explicit loops. Thank you. -pete |
|
#2
| |||
| |||
| 5 binc {each} 0 1 2 3 4 5 ....Paul "Peter Keller" <psilord@merlin.cs.wisc.edu> wrote in message news:48f80d02$0$9898$80265adb@spool.cs.wisc.edu... > Hello, > > I'm working on a parametric (hermite, bezier, b-spline, etc) > curve/surface/volume library as my first real piece of APL. > > I have a question about how to do a certain operation without loops. > > I need to construct a binomial coefficient and have written a function > like > this: > > n binc i > (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i > > This works for things like 5 binc 2, which is 10. > > My question is: if i is a vector, so I might call the function like this: > > 5 binc 0 1 2 3 4 5 > > How can I get the response of a vector like > 1 5 10 10 5 1 > from binc? > > Do I need an explicit loop to iterate the operation across vector i > {rho}i times? > > In scheme (for those who might know it), I could encapsulate binc into > a higher order function, currying one of the arguments, and then map it > across the vector i, like this: > > (map (lambda (x) (binc 5 x)) '(0 1 2 3 4 5)) > > But I don't know how to do a similar thing in APL without the explicit > loops. > > Thank you. > > -pete |
|
#3
| |||
| |||
| Though you really want to re-write your function: r {gets} n binc i r {gets} (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i So you can use the result in subsequent calculation. ....Paul "Paul Houle" <asmguru@yahoo.com> wrote in message news:qwUJk.2652$hc1.2401@flpi150.ffdc.sbc.com... > > 5 binc {each} 0 1 2 3 4 5 > > ...Paul > > "Peter Keller" <psilord@merlin.cs.wisc.edu> wrote in message > news:48f80d02$0$9898$80265adb@spool.cs.wisc.edu... >> Hello, >> >> I'm working on a parametric (hermite, bezier, b-spline, etc) >> curve/surface/volume library as my first real piece of APL. >> >> I have a question about how to do a certain operation without loops. >> >> I need to construct a binomial coefficient and have written a function >> like >> this: >> >> n binc i >> (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i >> >> This works for things like 5 binc 2, which is 10. >> >> My question is: if i is a vector, so I might call the function like this: >> >> 5 binc 0 1 2 3 4 5 >> >> How can I get the response of a vector like >> 1 5 10 10 5 1 >> from binc? >> >> Do I need an explicit loop to iterate the operation across vector i >> {rho}i times? >> >> In scheme (for those who might know it), I could encapsulate binc into >> a higher order function, currying one of the arguments, and then map it >> across the vector i, like this: >> >> (map (lambda (x) (binc 5 x)) '(0 1 2 3 4 5)) >> >> But I don't know how to do a similar thing in APL without the explicit >> loops. >> >> Thank you. >> >> -pete > > |
|
#4
| |||
| |||
| Paul Houle <asmguru@yahoo.com> wrote: > Though you really want to re-write your function: > > r {gets} n binc i > r {gets} (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i > > So you can use the result in subsequent calculation. > ...Paul > > "Paul Houle" <asmguru@yahoo.com> wrote in message > news:qwUJk.2652$hc1.2401@flpi150.ffdc.sbc.com... >> >> 5 binc {each} 0 1 2 3 4 5 Wow. I somehow had typed every other combination of {each} except the one you just did, which I tried and it worked just fine. That is pretty cool and makes me very happy since currying in this manner is a common idiom I wish to use. And I rewrote my functions about 5 minutes before you mentioned why as I had just puzzled out the VALUE ERROR I was getting in APLX. However, I have another function, berp, which is the berstein polynomial that takes the binomial coefficient parameters, plus a parameteric variable which represents a location on the bernstein polynomial curve. It looks like this: Z {gets} c berp u Z {gets} (c[2] binc c[1]) x (u*c[1]) x (1-u)*c[2]-c[1] And produces good answers: > 1 2 berp 0 0 > 1 2 berp .5 ..5 > 1 2 berp 1 0 However, when I try the same trick: 1 2 berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 It fails with a LENGTH ERROR on the marker on 1. Why doesn't {each} work in this context? Do I not have a vector on the left in the same manner that 5 binc {each} 0 1 2 3 4 5 did? Thank you. -pete |
|
#5
| |||
| |||
| You need to enclose the left argument (scalarizing it) to distribute it properly across all the right arguments. ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 ....Paul "Peter Keller" <psilord@merlin.cs.wisc.edu> wrote in message news:48f81aab$0$9898$80265adb@spool.cs.wisc.edu... > Paul Houle <asmguru@yahoo.com> wrote: >> Though you really want to re-write your function: >> >> r {gets} n binc i >> r {gets} (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i >> >> So you can use the result in subsequent calculation. >> ...Paul >> >> "Paul Houle" <asmguru@yahoo.com> wrote in message >> news:qwUJk.2652$hc1.2401@flpi150.ffdc.sbc.com... >>> >>> 5 binc {each} 0 1 2 3 4 5 > > Wow. I somehow had typed every other combination of {each} except the > one you just did, which I tried and it worked just fine. That is pretty > cool and makes me very happy since currying in this manner is a common > idiom I wish to use. > > And I rewrote my functions about 5 minutes before you mentioned why as I > had just puzzled out the VALUE ERROR I was getting in APLX. > > However, I have another function, berp, which is the berstein polynomial > that takes the binomial coefficient parameters, plus a parameteric > variable > which represents a location on the bernstein polynomial curve. > > It looks like this: > > Z {gets} c berp u > Z {gets} (c[2] binc c[1]) x (u*c[1]) x (1-u)*c[2]-c[1] > > And produces good answers: > >> 1 2 berp 0 > 0 > >> 1 2 berp .5 > .5 > >> 1 2 berp 1 > 0 > > However, when I try the same trick: > > 1 2 berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > > It fails with a LENGTH ERROR on the marker on 1. > > Why doesn't {each} work in this context? Do I not have a vector on the > left > in the same manner that 5 binc {each} 0 1 2 3 4 5 did? > > Thank you. > > -pete |
|
#6
| |||
| |||
| Paul Houle <asmguru@yahoo.com> wrote: > You need to enclose the left argument (scalarizing it) to distribute it > properly across all the right arguments. > > ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 Hrm.... So once inside the berp function, how does berp know that the left hand side is a vector of length 2 where index 1 is 1 and index 2 is 2, instead of thinking that the left hand side is a single vector which contains one element which is another vector containing 1 and 2? I'm definitely confused on the semantic reasoning for why {enclose} behaves correctly in this case. I'm unsure what the difference are between these and why the implementation of berp knows what the left hand side looks like in the 1st and 4th example: 1 2 berp .5 ({enclose}1 2) berp .5 1 2 berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 Thank you. -pete |
|
#7
| |||
| |||
| Peter Keller wrote: > Hello, > > I'm working on a parametric (hermite, bezier, b-spline, etc) > curve/surface/volume library as my first real piece of APL. > > I have a question about how to do a certain operation without loops. > > I need to construct a binomial coefficient and have written a function like > this: > > n binc i > (x/{iota}n) {divide} (x/{iota}i) x x/{iota}n-i > > This works for things like 5 binc 2, which is 10. > > My question is: if i is a vector, so I might call the function like this: > > 5 binc 0 1 2 3 4 5 > > How can I get the response of a vector like > 1 5 10 10 5 1 > from binc? > > Do I need an explicit loop to iterate the operation across vector i > {rho}i times? Why are you writing your own function? Dyadic ! (binomial coefficient) is a primitive scalar function which does everything you want. 2!5 10 {quad}IO{is}0 ({iota}6)!5 1 5 10 10 5 1 |
|
#8
| |||
| |||
| The berp function never "sees" the effects of the {each}. The {each} operator simply executes berp multiple times with the appropriate arguments and combines the results. {each} implicitly does a disclose of the left and right arguments, before each call to berp, pairing scalars beforehand in the normal scalar dyadic manner. Similar to how 1+3 4 5 executes as 1 1 1+3 4 5, ({enclose}1 2) berp{each} 0 .1 .2 executes as ((1 2)(1 2)(1 2)) berp{each} 0 .1 .2 It might be a good idea to play around with {enclose} and {each} on a primitive function to get a feel for how they work. For instance replace "berp" with "+" in the examples you're working with. ....Paul "Peter Keller" <psilord@merlin.cs.wisc.edu> wrote in message news:48f82939$0$9896$80265adb@spool.cs.wisc.edu... > Paul Houle <asmguru@yahoo.com> wrote: >> You need to enclose the left argument (scalarizing it) to distribute it >> properly across all the right arguments. >> >> ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > > Hrm.... So once inside the berp function, how does berp know that the left > hand side is a vector of length 2 where index 1 is 1 and index 2 is 2, > instead > of thinking that the left hand side is a single vector which contains > one element which is another vector containing 1 and 2? > > I'm definitely confused on the semantic reasoning for why {enclose} > behaves > correctly in this case. > > I'm unsure what the difference are between these and why the > implementation of berp knows what the left hand side looks like in the > 1st and 4th example: > > 1 2 berp .5 > ({enclose}1 2) berp .5 > 1 2 berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > > Thank you. > > -pete |
|
#9
| |||
| |||
| On Oct 17, 7:57*am, Peter Keller <psil...@merlin.cs.wisc.edu> wrote: > Paul Houle <asmg...@yahoo.com> wrote: > > You need to enclose the left argument (scalarizing it) to distribute it > > properly across all the right arguments. > > > * * ({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > > Hrm.... So once inside the berp function, how does berp know that the left > hand side is a vector of length 2 where index 1 is 1 and index 2 is 2, instead > of thinking that the left hand side is a single vector which contains > one element which is another vector containing 1 and 2? > > I'm definitely confused on the semantic reasoning for why {enclose} behaves > correctly in this case. > > I'm unsure what the difference are between these and why the > implementation of berp knows what the left hand side looks like in the > 1st and 4th example: > > * * *1 2 berp .5 > * * *({enclose}1 2) berp .5 > * * *1 2 berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > * * *({enclose}1 2) berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 > > Thank you. > > -pete An alternative to enclosing the left argument is to use the compose operator to curry it to a monadic function: 1 2{compose}berp {each} 0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 Sounds like that fits your thought more closely. Stephen editor@vector.org.uk |
|
#10
| |||
| |||
| James J. Weinkam <jjw@cs.sfu.ca> wrote: > Why are you writing your own function? Dyadic ! (binomial coefficient) > is a primitive scalar function which does everything you want. > > 2!5 > 10 > {quad}IO{is}0 > ({iota}6)!5 > 1 5 10 10 5 1 *sheepish grin* I hadn't realized that function was available.... I realize that I will not be writing good APL initially and have to unlearn habits from other languages to really understand APL. So, sometimes I may make missteps, like not realizing there was already something which would do exactly what I needed. ![]() Thank you. -pete |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.