Redistribution

This is a discussion on Redistribution within the APL forums in Programming Languages category; Redistribution A little function based on Benkard's Distributed Round showed from Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes an integer vector. Very nice, always correct and fast. Without some nice enhencements the core of the function is Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v or in text notation if unicode shouldn't work Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v where v is the given vector and n is the new sum to redistribute +/v←1 8 1 9 19 n←16 v Redo n 1 7 0 8 +/v Redo n 16 the result is correct but not as expected. If I should redistribute by hand the ...

Go Back   Application Development Forum > Programming Languages > APL

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #1  
Old 12-03-2007, 04:55 AM
tom7777777@gmx.de
Guest
 
Default Redistribution

Redistribution

A little function based on Benkard's Distributed Round showed from
Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
an integer vector. Very nice, always correct and fast. Without some
nice enhencements the core of the function is

Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
or in text notation if unicode shouldn't work
Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v

where v is the given vector and n is the new sum to redistribute

+/v←1 8 1 9
19
n←16
v Redo n
1 7 0 8
+/v Redo n
16
the result is correct but not as expected. If I should redistribute by
hand the result would be 1 7 1 7 because of the smallest relative
changes. I could sort the vector ..

+/v←9 8 1 1
19
v Redo n
8 6 1 1

.. gives another result but not as expected too. A third version ...

+/v←8 9 1 1
19
v Redo n
7 7 1 1

.. gives the result as expected.

Other examples ..

9 8 1 1 Redo 20
9 9 1 1
1 1 8 9 Redo 20
1 1 9 9
8 1 1 9 Redo 20
8 1 2 9
9 1 1 8 Redo 20
9 2 1 8
9 1 8 1 Redo 20
9 2 8 1
8 1 9 1 Redo 20
8 1 10 1

The last result is the one that I would like to have.

Is there a general (mathematical) solution that redistributes with
smallest relative changes(proportional)?

Thomas

Reply With Quote
  #2  
Old 12-03-2007, 05:06 PM
Phil Last
Guest
 
Default Re: Redistribution

On Dec 3, 9:55 am, tom7777...@gmx.de wrote:
> Redistribution
>
> A little function based on Benkard's Distributed Round showed from
> Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
> an integer vector. Very nice, always correct and fast. Without some
> nice enhencements the core of the function is
>
> Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
> or in text notation if unicode shouldn't work
> Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v
>
> where v is the given vector and n is the new sum to redistribute
>
> +/v←1 8 1 9
> 19
> n←16
> v Redo n
> 1 7 0 8
> +/v Redo n
> 16
> the result is correct but not as expected. If I should redistribute by
> hand the result would be 1 7 1 7 because of the smallest relative
> changes. I could sort the vector ..
>
> +/v←9 8 1 1
> 19
> v Redo n
> 8 6 1 1
>
> .. gives another result but not as expected too. A third version ...
>
> +/v←8 9 1 1
> 19
> v Redo n
> 7 7 1 1
>
> .. gives the result as expected.
>
> Other examples ..
>
> 9 8 1 1 Redo 20
> 9 9 1 1
> 1 1 8 9 Redo 20
> 1 1 9 9
> 8 1 1 9 Redo 20
> 8 1 2 9
> 9 1 1 8 Redo 20
> 9 2 1 8
> 9 1 8 1 Redo 20
> 9 2 8 1
> 8 1 9 1 Redo 20
> 8 1 10 1
>
> The last result is the one that I would like to have.
>
> Is there a general (mathematical) solution that redistributes with
> smallest relative changes(proportional)?
>
> Thomas


red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}

in the above which probably will show blanks for some of the
characters:

red<-{a{w{a+(sig a)times(iota rho a)in(|w)rho gradedown|a}a-+/w}w
+floor 0.5+w times(a-+/w)div+/w}

where a is alpha; w is omega

The function is called with the new total on the left and the original
vector on the right.
Not necessarily the shortest or most efficient. I just wrote down what
I thought my brain was doing.
The rounding is on the exact amount to be redistributed.
We then get the sum of the error which must be less than the length of
the vector and add that many ones (-ones?) to that many of the
greatest magnitude.

Seems to work but no guarantees. Also tested on mixed plus and minus.
Reply With Quote
  #3  
Old 12-03-2007, 05:21 PM
Phil Last
Guest
 
Default Re: Redistribution

On Dec 3, 10:06 pm, Phil Last <phil.l...@ntlworld.com> wrote:
> On Dec 3, 9:55 am, tom7777...@gmx.de wrote:
>
>
>
> > Redistribution

>
> > A little function based on Benkard's Distributed Round showed from
> > Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
> > an integer vector. Very nice, always correct and fast. Without some
> > nice enhencements the core of the function is

>
> > Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
> > or in text notation if unicode shouldn't work
> > Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v

>
> > where v is the given vector and n is the new sum to redistribute

>
> > +/v←1 8 1 9
> > 19
> > n←16
> > v Redo n
> > 1 7 0 8
> > +/v Redo n
> > 16
> > the result is correct but not as expected. If I should redistribute by
> > hand the result would be 1 7 1 7 because of the smallest relative
> > changes. I could sort the vector ..

>
> > +/v←9 8 1 1
> > 19
> > v Redo n
> > 8 6 1 1

>
> > .. gives another result but not as expected too. A third version ...

>
> > +/v←8 9 1 1
> > 19
> > v Redo n
> > 7 7 1 1

>
> > .. gives the result as expected.

>
> > Other examples ..

>
> > 9 8 1 1 Redo 20
> > 9 9 1 1
> > 1 1 8 9 Redo 20
> > 1 1 9 9
> > 8 1 1 9 Redo 20
> > 8 1 2 9
> > 9 1 1 8 Redo 20
> > 9 2 1 8
> > 9 1 8 1 Redo 20
> > 9 2 8 1
> > 8 1 9 1 Redo 20
> > 8 1 10 1

>
> > The last result is the one that I would like to have.

>
> > Is there a general (mathematical) solution that redistributes with
> > smallest relative changes(proportional)?

>
> > Thomas

>
> red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
>
> in the above which probably will show blanks for some of the
> characters:
>
> red<-{a{w{a+(sig a)times(iota rho a)in(|w)rho gradedown|a}a-+/w}w
> +floor 0.5+w times(a-+/w)div+/w}
>
> where a is alpha; w is omega
>
> The function is called with the new total on the left and the original
> vector on the right.
> Not necessarily the shortest or most efficient. I just wrote down what
> I thought my brain was doing.
> The rounding is on the exact amount to be redistributed.
> We then get the sum of the error which must be less than the length of
> the vector and add that many ones (-ones?) to that many of the
> greatest magnitude.
>
> Seems to work but no guarantees. Also tested on mixed plus and minus.


A counter example:

+/⎕←¯47 red 12 ¯14 ¯16 15 13

But I'm not sure why!
Reply With Quote
  #4  
Old 12-03-2007, 06:07 PM
Phil Last
Guest
 
Default Re: Redistribution

On Dec 3, 10:21 pm, Phil Last <phil.l...@ntlworld.com> wrote:
> On Dec 3, 10:06 pm, Phil Last <phil.l...@ntlworld.com> wrote:
>
>
>
> > On Dec 3, 9:55 am, tom7777...@gmx.de wrote:

>
> > > Redistribution

>
> > > A little function based on Benkard's Distributed Round showed from
> > > Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
> > > an integer vector. Very nice, always correct and fast. Without some
> > > nice enhencements the core of the function is

>
> > > Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
> > > or in text notation if unicode shouldn't work
> > > Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v

>
> > > where v is the given vector and n is the new sum to redistribute

>
> > > +/v←1 8 1 9
> > > 19
> > > n←16
> > > v Redo n
> > > 1 7 0 8
> > > +/v Redo n
> > > 16
> > > the result is correct but not as expected. If I should redistribute by
> > > hand the result would be 1 7 1 7 because of the smallest relative
> > > changes. I could sort the vector ..

>
> > > +/v←9 8 1 1
> > > 19
> > > v Redo n
> > > 8 6 1 1

>
> > > .. gives another result but not as expected too. A third version ...

>
> > > +/v←8 9 1 1
> > > 19
> > > v Redo n
> > > 7 7 1 1

>
> > > .. gives the result as expected.

>
> > > Other examples ..

>
> > > 9 8 1 1 Redo 20
> > > 9 9 1 1
> > > 1 1 8 9 Redo 20
> > > 1 1 9 9
> > > 8 1 1 9 Redo 20
> > > 8 1 2 9
> > > 9 1 1 8 Redo 20
> > > 9 2 1 8
> > > 9 1 8 1 Redo 20
> > > 9 2 8 1
> > > 8 1 9 1 Redo 20
> > > 8 1 10 1

>
> > > The last result is the one that I would like to have.

>
> > > Is there a general (mathematical) solution that redistributes with
> > > smallest relative changes(proportional)?

>
> > > Thomas

>
> > red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}

>
> > in the above which probably will show blanks for some of the
> > characters:

>
> > red<-{a{w{a+(sig a)times(iota rho a)in(|w)rho gradedown|a}a-+/w}w
> > +floor 0.5+w times(a-+/w)div+/w}

>
> > where a is alpha; w is omega

>
> > The function is called with the new total on the left and the original
> > vector on the right.
> > Not necessarily the shortest or most efficient. I just wrote down what
> > I thought my brain was doing.
> > The rounding is on the exact amount to be redistributed.
> > We then get the sum of the error which must be less than the length of
> > the vector and add that many ones (-ones?) to that many of the
> > greatest magnitude.

>
> > Seems to work but no guarantees. Also tested on mixed plus and minus.

>
> A counter example:
>
> +/⎕←¯47 red 12 ¯14 ¯16 15 13
>
> But I'm not sure why!


STUPID ERROR
red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
^
A small matter of an omega instead of an alpha and/or vice versa.
So ...
red←{⍺{⍵{⍺+(×⍵)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
Still not perfect ...
+/⎕←3 red ⍳9
0 0 0 0 0 0 0 2 1
3
Reply With Quote
  #5  
Old 12-04-2007, 03:30 AM
Morten Kromberg
Guest
 
Default Re: Redistribution

On Dec 3, 10:55 am, tom7777...@gmx.de wrote:

> Is there a general (mathematical) solution that redistributes with
> smallest relative changes(proportional)?


I remember trying that and getting told off by the financial
controller for putting the error into the largest numbers; problem was
the CEO knew the sales figures for the biggest regions by heart. So
instead, Sales for Iceland were up by 50% :-)

Morten
Reply With Quote
  #6  
Old 12-04-2007, 04:25 AM
aleph0
Guest
 
Default Re: Redistribution

> On Dec 4, 9:30 am, Morten Kromberg <mk...@dyalog.com> wrote:
> I remember trying that and getting told off by the financial
> controller for putting the error into the largest numbers; problem was
> the CEO knew the sales figures for the biggest regions by heart. So
> instead, Sales for Iceland were up by 50% :-)
>


I remember doing that in 1982 when I developed a methodology for
application on large 5 dimensional matices. The results were always
accepted by the legal department and the unions. Salesmen's pay was
being calculated on the basis of "unit" sales !





Reply With Quote
  #7  
Old 12-04-2007, 05:25 AM
Phil Last
Guest
 
Default Re: Redistribution

On Dec 3, 11:07 pm, Phil Last <phil.l...@ntlworld.com> wrote:
> On Dec 3, 10:21 pm, Phil Last <phil.l...@ntlworld.com> wrote:
>
>
>
> > On Dec 3, 10:06 pm, Phil Last <phil.l...@ntlworld.com> wrote:

>
> > > On Dec 3, 9:55 am, tom7777...@gmx.de wrote:

>
> > > > Redistribution

>
> > > > A little function based on Benkard's Distributed Round showed from
> > > > Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
> > > > an integer vector. Very nice, always correct and fast. Without some
> > > > nice enhencements the core of the function is

>
> > > > Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
> > > > or in text notation if unicode shouldn't work
> > > > Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v

>
> > > > where v is the given vector and n is the new sum to redistribute

>
> > > > +/v←1 8 1 9
> > > > 19
> > > > n←16
> > > > v Redo n
> > > > 1 7 0 8
> > > > +/v Redo n
> > > > 16
> > > > the result is correct but not as expected. If I should redistribute by
> > > > hand the result would be 1 7 1 7 because of the smallest relative
> > > > changes. I could sort the vector ..

>
> > > > +/v←9 8 1 1
> > > > 19
> > > > v Redo n
> > > > 8 6 1 1

>
> > > > .. gives another result but not as expected too. A third version ...

>
> > > > +/v←8 9 1 1
> > > > 19
> > > > v Redo n
> > > > 7 7 1 1

>
> > > > .. gives the result as expected.

>
> > > > Other examples ..

>
> > > > 9 8 1 1 Redo 20
> > > > 9 9 1 1
> > > > 1 1 8 9 Redo 20
> > > > 1 1 9 9
> > > > 8 1 1 9 Redo 20
> > > > 8 1 2 9
> > > > 9 1 1 8 Redo 20
> > > > 9 2 1 8
> > > > 9 1 8 1 Redo 20
> > > > 9 2 8 1
> > > > 8 1 9 1 Redo 20
> > > > 8 1 10 1

>
> > > > The last result is the one that I would like to have.

>
> > > > Is there a general (mathematical) solution that redistributes with
> > > > smallest relative changes(proportional)?

>
> > > > Thomas

>
> > > red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}

>
> > > in the above which probably will show blanks for some of the
> > > characters:

>
> > > red<-{a{w{a+(sig a)times(iota rho a)in(|w)rho gradedown|a}a-+/w}w
> > > +floor 0.5+w times(a-+/w)div+/w}

>
> > > where a is alpha; w is omega

>
> > > The function is called with the new total on the left and the original
> > > vector on the right.
> > > Not necessarily the shortest or most efficient. I just wrote down what
> > > I thought my brain was doing.
> > > The rounding is on the exact amount to be redistributed.
> > > We then get the sum of the error which must be less than the length of
> > > the vector and add that many ones (-ones?) to that many of the
> > > greatest magnitude.

>
> > > Seems to work but no guarantees. Also tested on mixed plus and minus.

>
> > A counter example:

>
> > +/⎕←¯47 red 12 ¯14 ¯16 15 13

>
> > But I'm not sure why!

>
> STUPID ERROR
> red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
> ^
> A small matter of an omega instead of an alpha and/or vice versa.
> So ...
> red←{⍺{⍵{⍺+(×⍵)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
> Still not perfect ...
> +/⎕←3 red ⍳9
> 0 0 0 0 0 0 0 2 1
> 3


On further reflection
⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵
is equivalent to
⌊0.5+⍵×⍺÷+/⍵
so ...
red←{⍺{⍵{⍺+(×⍵)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⌊0.5+⍵×⍺÷+/⍵}
is shorter and equivalent, not better on low totals which is where it
falls down.
Reply With Quote
  #8  
Old 12-07-2007, 06:43 AM
Phil Last
Guest
 
Default Re: Redistribution

On Dec 4, 10:25 am, Phil Last <phil.l...@ntlworld.com> wrote:
> On Dec 3, 11:07 pm, Phil Last <phil.l...@ntlworld.com> wrote:
>
>
>
> > On Dec 3, 10:21 pm, Phil Last <phil.l...@ntlworld.com> wrote:

>
> > > On Dec 3, 10:06 pm, Phil Last <phil.l...@ntlworld.com> wrote:

>
> > > > On Dec 3, 9:55 am, tom7777...@gmx.de wrote:

>
> > > > > Redistribution

>
> > > > > A little function based on Benkard's Distributed Round showed from
> > > > > Adrian Smith at Berlin 2000 and in Vector 20.3 page 87 redistributes
> > > > > an integer vector. Very nice, always correct and fast. Without some
> > > > > nice enhencements the core of the function is

>
> > > > > Redo←¯2-/0,⌊0.5+(+\v)×n÷+/v
> > > > > or in text notation if unicode shouldn't work
> > > > > Redo {assign} {negative}2-/0,{min}0.5+(+\v){multiply}n{divide}+/v

>
> > > > > where v is the given vector and n is the new sum to redistribute

>
> > > > > +/v←1 8 1 9
> > > > > 19
> > > > > n←16
> > > > > v Redo n
> > > > > 1 7 0 8
> > > > > +/v Redo n
> > > > > 16
> > > > > the result is correct but not as expected. If I should redistribute by
> > > > > hand the result would be 1 7 1 7 because of the smallest relative
> > > > > changes. I could sort the vector ..

>
> > > > > +/v←9 8 1 1
> > > > > 19
> > > > > v Redo n
> > > > > 8 6 1 1

>
> > > > > .. gives another result but not as expected too. A third version ....

>
> > > > > +/v←8 9 1 1
> > > > > 19
> > > > > v Redo n
> > > > > 7 7 1 1

>
> > > > > .. gives the result as expected.

>
> > > > > Other examples ..

>
> > > > > 9 8 1 1 Redo 20
> > > > > 9 9 1 1
> > > > > 1 1 8 9 Redo 20
> > > > > 1 1 9 9
> > > > > 8 1 1 9 Redo 20
> > > > > 8 1 2 9
> > > > > 9 1 1 8 Redo 20
> > > > > 9 2 1 8
> > > > > 9 1 8 1 Redo 20
> > > > > 9 2 8 1
> > > > > 8 1 9 1 Redo 20
> > > > > 8 1 10 1

>
> > > > > The last result is the one that I would like to have.

>
> > > > > Is there a general (mathematical) solution that redistributes with
> > > > > smallest relative changes(proportional)?

>
> > > > > Thomas

>
> > > > red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}

>
> > > > in the above which probably will show blanks for some of the
> > > > characters:

>
> > > > red<-{a{w{a+(sig a)times(iota rho a)in(|w)rho gradedown|a}a-+/w}w
> > > > +floor 0.5+w times(a-+/w)div+/w}

>
> > > > where a is alpha; w is omega

>
> > > > The function is called with the new total on the left and the original
> > > > vector on the right.
> > > > Not necessarily the shortest or most efficient. I just wrote down what
> > > > I thought my brain was doing.
> > > > The rounding is on the exact amount to be redistributed.
> > > > We then get the sum of the error which must be less than the length of
> > > > the vector and add that many ones (-ones?) to that many of the
> > > > greatest magnitude.

>
> > > > Seems to work but no guarantees. Also tested on mixed plus and minus..

>
> > > A counter example:

>
> > > +/⎕←¯47 red 12 ¯14 ¯16 15 13

>
> > > But I'm not sure why!

>
> > STUPID ERROR
> > red←{⍺{⍵{⍺+(×⍺)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
> > ^
> > A small matter of an omega instead of an alpha and/or vice versa.
> > So ...
> > red←{⍺{⍵{⍺+(×⍵)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵}
> > Still not perfect ...
> > +/⎕←3 red ⍳9
> > 0 0 0 0 0 0 0 2 1
> > 3

>
> On further reflection
> ⍵+⌊0.5+⍵×(⍺-+/⍵)÷+/⍵
> is equivalent to
> ⌊0.5+⍵×⍺÷+/⍵
> so ...
> red←{⍺{⍵{⍺+(×⍵)×(⍳⍴⍺)∊(|⍵) ⍒|⍺}⍺-+/⍵}⌊0.5+⍵×⍺÷+/⍵}
> is shorter and equivalent, not better on low totals which is where it
> falls down.


Sorry to bore you with this again but it came to me as I woke up this
morning...
The downgrade needs to be done on the original, not the new and
rounded distribution.
Unfortunately I haven't the time to sort out an algorithm without any
intermediate assignments but as I'm probably the only one that's
bothered here's a version with two of them that doesn't require Dyalog
and dynamic functions.
∇ r←a red w;e;n
[1] r←n+(×e)×(⍳⍴w)∊(|e←a-+/n←⌊0.5+w×a÷+/w)⍴⍒|w

Reply With Quote
  #9  
Old 12-18-2007, 01:54 AM
tom7777777@gmx.de
Guest
 
Default Re: Redistribution

Thank you very much!
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 04:41 PM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.