Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2000
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

RE: Re: "misbehaving" Union function

  • To: mathgroup at smc.vnet.net
  • Subject: [mg24124] RE: [mg24096] Re: [mg24075] "misbehaving" Union function
  • From: Wolf Hartmut <hwolf at debis.com>
  • Date: Wed, 28 Jun 2000 02:11:44 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

a note below

> -----Original Message-----
> From:	Andrzej Kozlowski [SMTP:andrzej at tuins.ac.jp]
To: mathgroup at smc.vnet.net
> Sent:	Tuesday, June 27, 2000 6:52 AM
> To:	mathgroup at smc.vnet.net
> Subject:	[mg24096] Re: [mg24075] "misbehaving" Union function
> 
> I have to send a correction to this posting. What I wrote was correct, and
> the solution given works, but the reason for the problem was not correctly
> identified. I looked at your example carefully and now I can see that when
> union is applied with the default setting the two elements that look the
> same are indeed sorted so as to be adjacent to each other. The problem is,
> however, that that are close enough tobe considered Equal but not to be
> considered SameQ. (You can see that by applying FullForm to your original
> answer). That's why the setting SameTest->Equal will remove the apparent
> duplicates while SameTest->Automatic (default) and SameTest->SameQ will
> not.
> 
> Andrzej
> on 00.6.23 11:04 PM, Andrzej Kozlowski at andrzej at tuins.ac.jp wrote:
> 
> > The explanation is as follows. Union admits one option: SameTest. This
> comes
> > with the default setting of Automatic. With this default setting the
> > elements of the list to which Union is being applied are first sorted in
> > canonical order and then only the adjacent elements are compared. This
> has
> > the advantage of speed. However, when working with approximate numbers,
> two
> > numbers (or list of numbers in your case) which are close enough to be
> > considered equal may not end up as being adjacent after sorting. When
> that
> > happens both may be kept. So the solution is to use an explicit setting
> for
> > SameTest: SameTest->Equal. If you use Union[...,SameTest->Equal] instead
> of
> > Union[...] in your example you will get the output:
> > 
> > Out[26]=
> > {{0, 0.}, {6, 2.}, {14, 6.}, {15, 7.}, {25, 11.}, {26, 12.}}
> > 
> > Andrzej Kozlowski
> > 
> > 
> > -- 
> > Andrzej Kozlowski
> > Toyama International University, JAPAN
> > 
> > For Mathematica related links and resources try:
> > <http://www.sstreams.com/Mathematica/>
> > 
> > 
> > 
> > on 6/23/00 3:26 PM, Felix Farkas at farkas at ica.epfl.ch wrote:
> > 
> >> Hi,
> >> i am trying to build up a list of points. The input is,
> >> a list of events. I use the Union function in order to
> >> avoid duplicate points. however i do not have the expected result.
> >> i really don't know where the error is coming from.
> >> Could somebody, please, tell me where is the fault?
> >> I would greatly appreciate any suggestions.
> >> 
> >> Many thanks in advance.
> >> Regards,
> >> Felix
> >> 
> >> Here is the function:
> >> 
> >> In[1]:= Genpoints[events_] :=
> >> Module[
> >> {ev = events, rate,
> >> duration, time, burst, bytes = 0, points = {}},
> >> rate := ee[[3]];
> >> duration := ee[[2]];
> >> time := ee[[1]];
> >> burst := ee[[4]];
> >> While[Length[ev] != 0,
> >> ee = First[ev];
> >> ev = Rest[ev];
> >> points = Union[points,
> >> If[rate == -1,
> >> (*then*)
> >> bytes += burst; {{time,
> >> bytes - burst}, {time, bytes}},
> >> (*else*)
> >> bytes += rate*duration;
> >> Print[{{time, bytes - rate*duration}, {time + duration,
> >> bytes}}];
> >> {{time, bytes -
> >> rate*duration}, {time + duration, bytes}}]
> >> ]
> >> ];
> >> points
> >> ]
> >> 
> >> The output generated is:
> >> 
> >> In[2]:= aa = {{0, 6, 0.3333333, 2, 2, 1},
> >> {6, 8, 0.5, 4, 2, 1}, {14, 1, 1, 1, 2, 1},
> >> {15, 10, 0.4, 4, 2, 1}, {25, 1, 1, 1, 2, 1}};
> >> In[3]:=  po2 = Genpoints[aa]
> >> Out[3]= {{0, 0.}, {6, 2.}, {6, 2.}, {14, 6.},
> >> {15, 7.}, {25, 11.}, {26, 12.}}
> >> 
> >> 
> >> 
> >>
> --------------------------------------------------------------------------
> ---
> >> Felix Farkas
> >> EPFL-DSC-ICA
> >> IN-Ecublens
> >> CH-1015 Lausanne
> >> Switzerland
> >> 
> >> tel:       0041 21 693 6601
> >> fax:       0041 21 693 6610
> >> email:     felix.farkas at epfl.ch
> >> 
> >> 
> >> 
> > 
> 
> -- 
> Andrzej Kozlowski
> Toyama International University
> JAPAN
> 
> http://platon.c.u-tokyo.ac.jp/andrzej/
> http://sigma.tuins.ac.jp/
> 
[Wolf Hartmut]  

Dear Felix,

Andrzej's explanation is correct, I just want to show how you would have
avoided the problems in first place. Essentially this is because after

  bytes += rate*duration; bytes - rate*duration

you don't get the old value for bytes, since the numerics isn't accurate.
You just have to avoid this operation of "looking back". For a short fix,
you can accumulate bytes only where it is needed, so 

Genpoints2[events_] := 
  Module[{ev = events, rate, duration, time, burst, bytes = 0, points = {}},

    rate := ee[[3]];
    duration := ee[[2]];
    time := ee[[1]];
    burst := ee[[4]];
    While[Length[ev] != 0, ee = First[ev];
      ev = Rest[ev];
      points = 
        Union[points, 
          If[rate == -1,(*then*) {{time, bytes}, {time, bytes += burst}},
            (*else*)
            Print[{{time, bytes}, {time + duration, bytes +
rate*duration}}];
            {{time, bytes}, {time + duration, bytes += rate*duration}}]]];
    points]

will not disturb you. However this programm makes very inefficient use of
Union, furthermore you make multiple access to the components of the event,
so I might propose you an alternative

Genpoints3[events_] := 
  Union @@ Block[{time, duration, rate, burst, scrap1, scrap2, bytes = 0}, 
      Function[ee, {time, duration, rate, burst, scrap1, scrap2} = ee; 
          If[rate == -1,(*then*) {{time, bytes}, {time, bytes += burst}},
            (*else*)
            Print[{{time, bytes}, {time + duration, bytes +
rate*duration}}];
            {{time, bytes}, {time + duration, bytes += rate*duration}}]] /@ 
        events] 

Kind regards, Hartmut 


  • Prev by Date: RE: Mathematica for High School Students
  • Next by Date: Re: Mathematica for High School Students
  • Previous by thread: RE: Re: "misbehaving" Union function
  • Next by thread: Re: "misbehaving" Union function