 # Boost :

From: Andy Little (andy_at_[hidden])
Date: 2006-03-27 14:44:27

"Michael Andersen Nexø" <nexo_at_[hidden]> wrote in message
news:e071gn\$irn\$1_at_sea.gmane.org...
>>
> Thanks!
>
>> point relative to line utilities e.g left_of are useful useful though I would
>> expect left_of to be able to tell me that the point is on the line too.
>> Presumably it could return 1 == left_of , 0 == on the line , -1 ==right_of
>> etc.
>>
> Ah, yes, the classic operator<() vs. strcmp() divide :-)
>
> wouldn't make much sense having a left_of returning an strcmp-like int.
> At least to me it would be a little unclear what the sign of the int
> returned meant. But mostly because the functionality you request is
>
> What is the placement of p relative to the ray going from a to b?
> cross(b - a, p - a) > 0 // left of
> == 0 // on the line
> < 0 // right of
>
> (BTW, left_of etc. was intentionally hidden as an implementation detail
> of the convex_hull algorithm, because I wasn't sure whether or not it
> would make sense to add this to the general interface when cross product

Actually I'm beginning to get confused about use of a left_of function actually
means anyway. I'm assuming that e.g left_of is defined as taking any arbitrary
point on the line and sweeping another line (say)anti-clockwise round that point
180 degrees. If you hit the point the point is on the left side of the line,
else on the right? But I'm not sure what the cross function is. AFAIK a
cross_product only applies in 3D?

>> Not much in favour of the cast functions. The need to cast often usually
>> indicates a design problem. In this case I think it may be because specifying
>> a
>> point type is flawed (as I am often fond of repeating ) unless you define
>
> Do you mean that distinguishing between point and vectors in the type
> system should be avoided altogether? If so, I'm afraid I'm in the other
> camp of that holy war :-)
>
> I personally like the fact that the different semantics of the two are
> reflected in the C++ type system. Anyway, if I've understood your
> comment correctly I'd be glad to hear your arguments for ditching a
> point type altogether.

The problem is that addition is not defined for points. (it can be defined
but then there would be no material difference between points and vectors.)
However addition is necessary for points. (Apparently it is doable using
"grassmann points" but I cant find what that means in practise). So to an
example where the issue arises...

As I understand it you downloaded my geometry library. There is a bezier curve
in <boost/geometry/three_d/bezier4.hpp>. For reasons I cant quite fathom I have
left a lot of extraneous matter in bezier4, so I have attached to this post an
modified version of bezier4.hpp as bezier4a.hpp (I've also attached an updated
version of <boost/geometry/three_d/vect.hpp> which I hope allows the example to
compile with gcc FWIW. That refers to another issue which I'll bring up later).

Anyway in bezier4a.hpp. The crucial function is the bezier4a.at(pos), where pos
is a float. bezier4a.at(n) returns the position of the relevent point on the
curve. I cant remember exactly about the origin of the function, but it is some
sort of polynomial and polynomials are frequently used in calculating splines
such as beziers and NURBS, so they are quite frequent. Anyway point addition is
quite prominent in the calculation. (FWIW I also attached test.cpp which can be
used to test the bezier functionality. If you dont have my pqs lib then comment
out the reference to boost pqs and use the Float version instead).

Alternatively it would be interesting to see how you would implement the
function without point addition.. (I guess one way would be to reimplement it in
terms of subtraction but that would seem to me to involve a lot of
hoop-jumping).

>> Expression template stuff is a general utility is it not? Could be used
outside
>> geometry library, so it might be better to split that.
>
> Are you saying that expression templates could be achieved by somehow
> using an "Expression Templates Library" developed independently of this
> geometry library? If so, that sounds interesting -- I'd love to hear
> how. Can you direct me to relevant info on that? Thx.

Basically just wrap T in some array type whose operator Op then build the
expression template in an expression. But as you say later is it worth it ?

>> The use of promotion_traits etc might soon be superceded by Boost.Typeof
>> which should be
>> available in the next version of the boost distro. Also could be done so as
>> both
>> et and not et could be used together?
>>
>
> I agree totally. In fact, I wouldn't be surprised if my type promotion
> rules are wrong in a number of odd corner cases. A lot of this was
> simply written at a time when the geometry classes weren't dependent on
> Boost. But, in this context using BOOST_TYPEOF as you do (and eventually
> using the decltype construct) is obviously to be preferred.

Right. After I wrote that I remembered that due to a longstanding implementation
issue, gcc wont handle TYPEOF in return types. The attached vect.hpp shows the
workaround, which is basically to do as you are currently doing anyway. I guess
you could replace promotion_traits with Boost_typeof. Actually its a trivial
point ... sorry.

> I think it would be quite easy to make ET and non-ET geometry classes
> coexist (at the expense of complicating the interface a bit by another
> template parameter). This is a good point that needs consideration.
>
> But, actually I'm not even too convinced that expression templates are
> worth the complexity for the low dimensionalities typically used for
> most geometry-related computations. The few performance tests I've done
> tend to show that the benefits of ET starts to kick in at D>5 or so.

I figured that ET needs large matrices to offer any gain too :-)

> Maybe the time is better spent elsewhere (e.g. doing SIMD
> implementations for various architectures).

I wouldnt know where to start I'm afraid. I recently chucked reams of x86
architecture information away and decided to leave it to the experts ;-)

> The reason I opted to keep the ET stuff in there is because the method
> of implementing it used is so non-obtrusive to the core interface and
> that it can be easily be switched on/off. (BTW, the approach to
> Expression Templates that I've used is blatantly copied from
> Vandevoorde's and Josutti's book. I've found it a very clean way of
> ensuring that the interface of all the expression templates stay the same.)
>
>> Nice to see a GUI based example, though I havent tested it yet. One day maybe
>> in
>> the distant future it will use the cross -platform C++ standard GUI system
>> ;-)
>>
>
> Yeah, the C++ Standard GUI is expected to arrive right after the
> paperless office :-)

No comment on your next section. It seems like these are big and difficult
issues which I dont think I can say anything useful about without a lot more
thought or detailed explanation.

> No, seriously, I think this is one of the best arguments for the
> approach I'm putting forward: creating a STL-like split between the
> data types and the algorithms and utilities.
>
> It's naive to believe that all the many graphics subsystems in existence
> will start using the same geometry primitives in their interfaces. For
> the foreseeable future, different platforms (even subsystems) will have
> different ways of representing a vector.
>
> Just as we didn't want to rewrite a sorting algorithm for every
> container in existence, we don't want to be having to rewrite our
> geometric algorithms over and over again for every geometric primitive
> on all the different platforms out there.
>
> My approach has been to try and provide geometric primitives that are
> both able work alone *and* work as adapter classes around platform
> specific types with virtually no overhead. These primitives can then be
> used for 1) writing generic geometry-related algorithms, 2) facilitate
> seamless interaction between otherwise incompatible geometry primitives
> from different subsystems.
>
> I'm certain the design I've can be improved vastly, but I think it would
> be regrettable if the overall *design goal* described above was not
> included in a Boost Generic Geometry Library.

I guess it might help to go into some more detail about the above with some
useage examples etc.

>> Overall there seems to be a lot of useful stuff here.
>> The previous discussion re the minimum primitives seems to hold
>> (vector,matrix,
>> quaternion).
>
> Setting aside our little discrepancy about points ;-), wouldn't
> homogenous coordinates also be worthwhile?

Yes and homogeneous matrices maybe.

I have a feeling that they
> would be hard to implement by means of other primitives?

If they were limited to arithmetic then they are just structurally vectors of
Dimension +1 per dimension AFAIK. Converting between homogenous and
non-homogenous might be common though I think.

> Also, would there be any difference between boost::quarternion and
> boost::geometry::quarternion? (Please excuse me, I only have very skimpy

So do I. My feeling is just try boost:quaternion and see if it can be made to
work. Then see if Hubert Holin is interested in modifying it. I cant see why he
would object, as basically AFAIK this is quaternions starring role. The main
problem is if it needs major interface changes. But at that point a decision can
be made whether the original can/will be used/modified or not.

>> Is anyone interested to start on moving a Boost.Geometry lib forward now?
>
> Absolutely. I'm already putting whatever little time I have into it and
> would love to team up with "kindred spirits" in this forum. But, perhaps
> we need to spend a little bit more time making sure we're on the same
> page regarding the rationale and scope of this library. This would by my
> bullet-point style take on that.
>
> Rationale:
>
> * Create nice, clean, "Standard C++"-like core geometry primitives,
> such as vector, matrix (and perhaps point, quarternion, homogenous
> vector). These would differ from uBLAS from the fact that their
> sizes were given at compile time (closer to tvmet).

OK. I understand this bit!

> * Create the necessary traits/adapter infrastructure for writing
> generic algorithms independently of the underlying geometry
> primitives, thus providing a framework for writing:
> * Generic utilities and algorithms lying in the realm of computational
> geometry. Algorithms should be generic in terms of both storage and
> scalar type used for the geometry primitives, and the dimensionality
> (the latter obviously only whenever applicable).

I assume the containers themselves are the standard ones...arrays, lists,vectors
etc? It might need some examples to clarify what you mean....

> Features that I see as important:
>
> * Primitives should be template'd on type, dimensionality and storage.
> * Care should be taken in dealing with the limited precision in typical
> scalar types when writing the operators, utilities and algorithms.
> (Adhering to C++ style promotion partly helps with this, but
> allowing for more user control over promotion is probably necessary.)

Ok... BTW (trivia) One issue I have is with C++ integer division . 1/2
(should go to) -->
0.5.
Another operator could have been used to represent integer-truncate division e.g
1 div 2 --> 0
Anyway I'd say this is a detail...

> * Interaction between primitives with different scalar types should be
> allowed, but truncation warnings should be generated when it is not
> done explicitly by the user.

An alternative is to make use of Boost.Numeric.Converter to downcast
http://www.boost.org/libs/numeric/conversion/doc/index.html

It can also use round to nearest rather than truncation in converting float to
int. Its used in my pqs library. Throws an exception if the input is out of
range too.

> * Expression templates are not a design goal in itself, but if the
> interface overhead is small and it is possible to switch it off, it
> should be considered.

But only if there are benefits which, because of the small dimensionality of the
matrices, seems dubious.

regards
Andy Little

begin 666 bezier4a.hpp
M(VEF;F1E9B!"3T]35%]'14]-151265]42%)%15]\$7T)%6DE%4C1!7TA04%])
M3D-,541%1 T*(V1E9FEN92!"3T]35%]'14]-151265]42%)%15]\$7T)%6DE%
M7TU30U]615(@/CT@,3(P,"D-"B,@('!R86=M82!O;F-E#0HC96YD:68-"@T*
M+R\@0V]P>7)I9VAT(\$%N9')E=R!,:71T;&4@,C P-0T*+R\-"B\O(\$1I<W1R
M:6)U=&5D('5N9&5R('1H92!";V]S="!3;V9T=V%R92!,:6-E;G-E+"!697)S
M:6]N(#\$N,"X@#0HO+R H4V5E(&%C8V]M<&%N>6EN9R!F:6QE(\$Q)0T5.4T5?
M,5\P+G1X="!O<B!C;W!Y(&%T( T*+R\@:'1T<#HO+W=W=RYB;V]S="YO<F<O
M3\$E#14Y315\Q7S N='AT*0T*#0HO*@T*(" @(#0@<&]I;G0_at_8F5Z:65R("X@
M#0H@(" @02!4<G5E(&)E>FEE<B!S:&]U;&0_at_86QL;W<@87)B:71R87)Y(&YU
M;6)E<B!O9B!P;VEN=',@:6XN#0H@(" @57-E(&)E>FEE<C0N870H1FQO870@
M8V]N<W0@)B!P*2!T;R!G970@=&AE('!O:6YT(&%T(' @*'=H97)E(" P(#P]
M(' @/#T@,2DN#0H-"BHO#0HC:6YC;'5D92 \<W1D97AC97!T/@T*;F%M97-P
M86-E(&)O;W-T>VYA;65S<&%C92!G96]M971R>7MN86UE<W!A8V4@=&AR965?
M9'L-"@T*(" @('1E;7!L871E(#P-"B @(" @(" @='EP96YA;64_at_4&]I;G14
M>7!E#0H@(" @/@T*(" @('-T<G5C="!B97II97(T87L-"B @(" @(" @='EP
M961E9B!0;VEN=%1Y<&4@<&]I;G1?='EP93L-"B @(" @(" @<&]I;G1?='EP
M92!A+&(L8RQD.PT*(" @(" @#0H@(" @(" @(&)E>FEE<C1A* T*(" @(" @
M(" @(" @<&]I;G1?='EP92!C;VYS=" F(&%?:6XL#0H@(" @(" @(" @("!P
M;VEN=%]T>7!E(&-O;G-T("8_at_8E]I;BP-"B @(" @(" @(" @('!O:6YT7W1Y
M<&4_at_8V]N<W0@)B!C7VEN+ T*(" @(" @(" @(" @<&]I;G1?='EP92!C;VYS
M=" F(&1?:6X-"B @(" @(" @*0T*(" @(" @(" Z(&\$H85]I;BDL8BAB7VEN
M*2QC*&-?:6XI+&0H9%]I;BD-"B @(" @(" @>PT*(" @(" @("!]( T*(" @
M(" @( T*(" @(" @(" O+R!T(&UU<W0_at_8F4@8F5T=V5E;B!B971W965N(# @
M86YD(#\$-"B @(" @(" @+R\@:68@=#T],"!O=71P=70@/3T@<&]I;G0_at_80T*
M(" @(" @(" O+R!I9B!T(#T](#\$@;W5T<'5T(#T]('!O:6YT(&0-"B @(" @
M(" @+R\@;W1H97(@=F%L=65S(&QI92!B971W965N+@T*(" @(" @(" O+R!T
M:')O=W,@;W5T7V]F7W)A;F=E#0H@(" @(" @('!O:6YT7W1Y<&4_at_870H(&-O
M;G-T(&1O=6)L92 F('0I8V]N<W0-"B @(" @(" @>PT*(" @(" @(" @(" @
M:68@*" H=" \(# I('Q\("@@=" ^(#\$I*7L-"B @(" @(" @(" @(" @("!T
M:')O=R!S=&0Z.F]U=%]O9E]R86YG92_at_B8F5Z:65R(&%T(&%R9W5M96YT(&]U
M="!O9B!R86YG92(I.PT*(" @(" @(" @(" @?0T*(" @(" @(" @(" @9&]U
M8FQE(&-O;G-T(&]N95]M7W0@/2 Q("T@=#L-"B @(" @(" @(" @(&1O=6)L
M92!C;VYS="!O;F5?;5]T,B ](&]N95]M7W0@*B!O;F5?;5]T.PT*(" @(" @
M(" @(" @9&]U8FQE(&-O;G-T(&]N95]M7W0S(#T@;VYE7VU?=#(@*B!O;F5?
M;5]T.PT*(" @(" @(" @(" @9&]U8FQE(&-O;G-T('0R(#T@=" J('0[#0H@
M(" @(" @(" @("!D;W5B;&4_at_8V]N<W0@=#,@/2!T,B J('0[#0H@( T*(" @
M(" @(" @(" @<&]I;G1?='EP92!R97-U;'0@#0H@(" @(" @(" @(" @(" @
M/2!O;F5?;5]T,R J(&\$@#0H@(" @(" @(" @(" @(" @*R S("H@=" J(&]N
M95]M7W0R("H_at_8@T*(" @(" @(" @(" @(" @("L@,R J('0R("H@;VYE7VU?
M=" J(&,-"B @(" @(" @(" @(" @(" K('0S("H_at_9#L-"B @(" @(" @(" @
M(')E='5R;B!R97-U;'0[#0H@(" @(" @('T@( T*(" @('T[#0H-"GU]?2\O
F8F]O<W0Z.F=E;VUE=')Y.CIT:')E95]D#0H-"B-E;F1I9_at_T*#0H`
`
end

begin 666 test.cpp
M(VEN8VQU9&4@/&)O;W-T+V=E;VUE=')Y+W1H<F5E7V0O8F5Z:65R-&\$N:'!P
M/@T*(VEN8VQU9&4@/&)O;W-T+V=E;VUE=')Y+W1H<F5E7V0O=F5C=%]O=70N
M:'!P/@T*(VEN8VQU9&4@/&)O;W-T+W!Q<R]T,5]Q=6%N=&ET>2]T>7!E<R]O
M=70O;&5N9W1H+FAP<#X-"B-I;F-L=61E(#QB;V]S="]R871I;VYA;"YH<' ^
M#0HC:6YC;'5D92 \:6]S=')E86T^#0H-"B\O=V]R:W,@9F]R('!Q<R!Q=6%N
M=&ET>2!O<B!F;&]A="!V86QU95]T>7!E<R -"G1Y<&5D968@(&)O;W-T.CIP
M<7,Z.FQE;F=T:#HZ;6T@(" @(" @(" @(" @("!L96YG=&@[#0HO+W1Y<&5D
M968_at_9&]U8FQE(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(&QE
M;F=T:#L-"@T*='EP961E9B @8F]O<W0Z.F=E;VUE=')Y.CIT:')E95]D.CIV
M96-T/&QE;F=T:#X@<&]I;G0[#0IT>7!E9&5F("!B;V]S=#HZ9V5O;65T<GDZ
M.G1H<F5E7V0Z.F)E>FEE<C1A/'!O:6YT/B!B97II97([#0H-"FEN="!M86EN
M*"D-"GL-"B @("!T<GE[#0H@(" @(" @("\O(#0@<&]I;G1S(&1E9FEN:6YG
M(&\$@8F5Z:65R(&-U<G9E+@T*(" @(" @(" O+R!C=7)V92!T;W5C:&5S('1A
M;F=E;G0@=&\@=C\$@+3X@=C(@870@=C\$-"B @(" @(" @+R\@86YD('1A;F=E
M;G0@=&\@=C,@+3X@=C0_at_870@=C0-"B @(" @(" @<&]I;G0@=C\$H;&5N9W1H
M*# I+&QE;F=T:"@P*2QL96YG=&@H,"DI.PT*(" @(" @("!P;VEN="!V,BAL
M96YG=&@H,2DL;&5N9W1H*# I+&QE;F=T:"@P*2D[#0H@(" @(" @('!O:6YT
M('8S*&QE;F=T:"@R*2QL96YG=&@H,"DL;&5N9W1H*# I*3L-"B @(" @(" @
M<&]I;G0@=C0H;&5N9W1H*#(I+&QE;F=T:"@Q*2QL96YG=&@H,"DI.PT*(" @
M(" @( T*(" @(" @("!B97II97(@8C\$H=C\$L=C(L=C,L=C0I.PT*(" @(" @
M(" O+R!N7W!O:6YT<R!G:79E<R!T:&4@;G5M8F5R(&]F('!O:6YT<R!R97%U
M:7)E9"!T;R!R97!R97-E;G0@=&AE(&-U<G9E#0H@(" @(" @(&EN="!C;VYS
M="!N7W!O:6YT<R ](#\$P.PT*(" @(" @("!F;W(H(&EN="!I(#T@,#L@:2 \
M(&Y?<&]I;G1S.R K*VDI>PT*(" @(" @(" @(" @+R]R871I;VYA;"!I<R!C
M;VYV96YI96YT('1O(&ET97)A=&4_at_8F5T=V5E;B P(&%N9" Q('5S:6YG(&%N
M(&EN= T*(" @(" @(" @(" @8F]O<W0Z.G)A=&EO;F%L/&EN=#X@<BAI+&Y?
M<&]I;G1S+3\$I.PT*(" @(" @(" @(" @+R\@8F5Z:65R+F%T('=A;G1S(&\$@
M;G5M8F5R(&)E='=E96X@,"!A;F0@,0T*(" @(" @(" @(" @<W1D.CIC;W5T
M(#P\(&(Q+F%T*&)O;W-T.CIR871I;VYA;%]C87-T/&1O=6)L93XH<BD@*2 \
M/"=<;B<[( T*(" @(" @("!]#0H@(" @(" @( T*(" @('UC871C:"AS=&0Z
M.F]U=%]O9E]R86YG92 F(&4I#0H@(" @>PT*(" @(" @("!S=&0Z.F-O=70@
B/#P_at_92YW:&%T*"D@/#P@)UQN)SL-"B @("!]#0H-"GT-"@``
`
end

begin 666 vect.hpp
M(VEF;F1E9B!"3T]35%]'4D%02\$E#04Q?5\$A2145?1%]614-47TA04%])3D-,
M541%1 T*(V1E9FEN92!"3T]35%]'4D%02\$E#04Q?5\$A2145?1%]614-47TA0
M15(@/CT@,3(P,"D-"B,@('!R86=M82!O;F-E#0HC96YD:68-"@T*+R\@0V]P
M>7)I9VAT(\$%N9')E=R!,:71T;&4@,C P-0T*+R\-"B\O(\$1I<W1R:6)U=&5D
M('5N9&5R('1H92!";V]S="!3;V9T=V%R92!,:6-E;G-E+"!697)S:6]N(#\$N
M,"X@#0HO+R H4V5E(&%C8V]M<&%N>6EN9R!F:6QE(\$Q)0T5.4T5?,5\P+G1X
M="!O<B!C;W!Y(&%T( T*+R\@:'1T<#HO+W=W=RYB;V]S="YO<F<O3\$E#14Y3
M15\Q7S N='AT*0T*#0HO*@T*(" @(#-D('9E8W0_at_9&5F:6YI=&EO;B K(&]P
M97)A=&EO;G,-"BHO#0H-"B-I;F-L=61E(#QB;V]S="]G96]M971R>2]T:')E
M95]D+W9E8W1?9&5F+FAP<#X-"B-I;F-L=61E(#QB;V]S="]T>7!E;V8O='EP
M96]F+FAP<#X-"B-I;F-L=61E(#QB;V]S="]U=&EL:71Y+V5N86)L95]I9BYH
M<' ^#0HC:6YC;'5D92 \8F]O<W0O='EP95]T<F%I=',O:7-?87)I=&AM971I
M8RYH<' ^#0H-"FYA;65S<&%C92!B;V]S='MN86UE<W!A8V4_at_9V5O;65T<GE[
M(&YA;65S<&%C92!T:')E95]D>PT*#0H@(" @=&5M<&QA=&4@/'1Y<&5N86UE
M(%1,+"!C:&%R(\$]P+"!T>7!E;F%M92!44CX-"B @("!S=')U8W0_at_8FEN;W [
M#0H-"B @("!T96UP;&%T92 \='EP96YA;64_at_5\$PL('1Y<&5N86UE(%12/@T*
M(" @('-T<G5C="!B:6YO<#Q43"PG*R<L5%(^#0H@(" @>PT*(" @(" @("!T
M>7!E9&5F(\$)/3U-47U194\$5/1E]44\$PH(%1,*"D@*R!44B_at_I*2!T>7!E.PT*
M(" @('T[#0H-"B @("!T96UP;&%T92 \='EP96YA;64_at_5\$PL('1Y<&5N86UE
M(%12/@T*(" @('-T<G5C="!B:6YO<#Q43"PG+2<L5%(^#0H@(" @>PT*(" @
M(" @("!T>7!E9&5F(\$)/3U-47U194\$5/1E]44\$PH(%1,*"D@+2!44B_at_I*2!T
M>7!E.PT*(" @('T[#0H-"B @("!T96UP;&%T92 \='EP96YA;64_at_5\$PL('1Y
M<&5N86UE(%12/@T*(" @('-T<G5C="!B:6YO<#Q43"PG*B<L5%(^#0H@(" @
M>PT*(" @(" @("!T>7!E9&5F(\$)/3U-47U194\$5/1E]44\$PH(%1,*"D@*B!4
M4B_at_I*2!T>7!E.PT*(" @('T[#0H@(" @=&5M<&QA=&4@/'1Y<&5N86UE(%1,
M+"!T>7!E;F%M92!44CX-"B @("!S=')U8W0_at_8FEN;W \5\$PL)R\G+%12/@T*
M(" @('L-"B @(" @(" @='EP961E9B!"3T]35%]465!%3T9?5%!,*"!43"@I
M("\@5%(H,2DI('1Y<&4[#0H@(" @?3L-"@T*#0H@(" @=&5M<&QA=&4@/'1Y
M<&5N86UE(%1,+"!T>7!E;F%M92!44CX-"B @("!I;FQI;F4-"B @("!V96-T
M(#QT>7!E;F%M92!B:6YO<#P_at_5\$PL)RLG+%12/CHZ='EP93X-"B @("!O<&5R
M871O<B K*"!V96-T/%1,/B!C;VYS=" F(&QH<RP@=F5C=#Q44CX_at_8V]N<W0@
M)B!R:',I#0H@(" @>PT*(" @(" @("!"3T]35%]465!%3T9?5%!,*&QH<R K
M(')H<RD@<F5S=6QT*&QH<RYX("MR:',N>"P@;&AS+GDK<FAS+GDL(&QH<RYZ
M("L@<FAS+GHI.PT*(" @(" @("!R971U<FX@<F5S=6QT.PT*(" @('T-"@T*
M(" @('1E;7!L871E(#QT>7!E;F%M92!43"P@='EP96YA;64_at_5%(^#0H@(" @
M:6YL:6YE#0H@(" @=F5C=" \='EP96YA;64_at_8FEN;W \(%1,+"<M)RQ44CXZ
M.G1Y<&4^#0H@(" @;W!E<F%T;W(@+2@@=F5C=#Q43#X_at_8V]N<W0@)B!L:',L
M('9E8W0\5%(^(&-O;G-T("8@<FAS*0T*(" @('L-"B @(" @(" @0D]/4U1?
M5%E014]&7U103"AL:',@+2!R:',I(')E<W5L="AL:',N>" M<FAS+G_at_L(&QH
M<RYY+7)H<RYY+"!L:',N>B M(')H<RYZ*3L-"B @(" @(" @<F5T=7)N(')E
M<W5L=#L-"B @("!]#0H-"B @("!T96UP;&%T92 \='EP96YA;64_at_5\$PL('1Y
M<&5N86UE(%12/@T*(" @(&EN;&EN90T*(" @('1Y<&5N86UE(&)O;W-T.CIE
M;F%B;&5?:68\#0H@(" @(" @(&)O;W-T.CII<U]A<FET:&UE=&EC/%12/BP-
M"B @(" @(" @=F5C=" \='EP96YA;64_at_8FEN;W \(%1,+"<J)RQ44CXZ.G1Y
M<&4^#0H@(" @/CHZ='EP92 -"B @("!O<&5R871O<B @*B@@=F5C=#Q43#X@
M8V]N<W0@)B!L:',L(%12(&-O;G-T("8@<FAS*0T*(" @('L-"B @(" @(" @
M0D]/4U1?5%E014]&7U103"AL:',@*B!R:',I(')E<W5L="AL:',N>" J<FAS
M+"!L:',N>2 J(')H<RQL:',N>B J(')H<RD[#0H@(" @(" @(')E='5R;B!R
M97-U;'0[#0H@(" @?0T*#0H@(" @=&5M<&QA=&4@/'1Y<&5N86UE(%1,+"!T
M>7!E;F%M92!44CX-"B @("!I;FQI;F4-"B @("!T>7!E;F%M92!B;V]S=#HZ
M96YA8FQE7VEF/ T*(" @(" @("!B;V]S=#HZ:7-?87)I=&AM971I8SQ43#XL
M#0H@(" @(" @('9E8W0@/'1Y<&5N86UE(&)I;F]P/"!43"PG*B<L5%(^.CIT
M>7!E/@T*(" @(#XZ.G1Y<&4@#0H@(" @;W!E<F%T;W(@("HH(%1,(&-O;G-T
M("8@;&AS+"!V96-T/%12/B!C;VYS=" F(')H<RD-"B @("![#0H@(" @(" @
M(\$)/3U-47U194\$5/1E]44\$PH;&AS("H@<FAS*2!R97-U;'0H;&AS("IR:',N
M>"P@;&AS("H@<FAS+GDL;&AS("H@<FAS+GHI.PT*(" @(" @("!R971U<FX@
M<F5S=6QT.PT*(" @('T-"@T*#0H@(" @=&5M<&QA=&4@/'1Y<&5N86UE(%1,
M+"!T>7!E;F%M92!44CX-"B @("!I;FQI;F4-"B @("!T>7!E;F%M92!B;V]S
M=#HZ96YA8FQE7VEF/ T*(" @(" @("!B;V]S=#HZ:7-?87)I=&AM971I8SQ4
M4CXL#0H@(" @(" @('9E8W0@/'1Y<&5N86UE(&)I;F]P/"!43"PG+R<L5%(^
M.CIT>7!E/@T*(" @(#XZ.G1Y<&4@#0H@(" @;W!E<F%T;W(@("\H('9E8W0\
M5\$P^(&-O;G-T("8@;&AS+"!44B!C;VYS=" F(')H<RD-"B @("![#0H@(" @
M(" @(\$)/3U-47U194\$5/1E]44\$PH;&AS("\@<FAS*2!R97-U;'0H;&AS+G@@
M+R!R:',L(&QH<RYY("\@<FAS+"!L:',N>B O(')H<RD[#0H@(" @(" @(')E
M='5R;B!R97-U;'0[#0H@(" @?0T*(" @('1E;7!L871E(#QT>7!E;F%M92!6
M86QU95]T>7!E/@T*(" @(%9A;'5E7W1Y<&4-"B @("!M86=N:71U9&4H('9E
M8W0\5F%L=65?='EP93X_at_8V]N<W0@)B!V*0T*(" @('L-"B @(" @(" @5F%L
M=65?='EP92!R97-U;'0@/2!S<7)T*'8N>" J('8N>" K('8N>2 J('8N>2 K
M('8N>B J('8N>BD[#0H@(" @(" @(')E='5R;B!R97-U;'0[#0H@(" @?0T*
M#0H@(" @=&5M<&QA=&4@/'1Y<&5N86UE(%0^( T*(" @('1Y<&5N86UE(&)I
M;F]P/"!4+"<J)RQ4/CHZ='EP90T*(" @(&1O=%]P<F]D=6-T*" -"B @(" @
M(" @=F5C=#Q4/B!C;VYS=" F(&QH<RP-"B @(" @(" @=F5C=#Q4/B!C;VYS
M=" F(')H<PT*(" @("E[#0H@(" @(" @('1Y<&5D968_at_0D]/4U1?5%E014]&
M7U103"@@5"@I("H_at_5"@I*2!R97-U;'1?='EP93L-"B @(" @(" @<F5S=6QT
M7W1Y<&4@<F5S=6QT( T*(" @(" @(" ](&QH<RYX("H@<FAS+G@@*R!L:',N
M>2 J(')H<RYY(" K(&QH<RYZ("H@<FAS+GH[#0H@(" @(" @(')E='5R;B!R
M97-U;'0[#0H@(" @?0T*#0H@(" @=&5M<&QA=&4\='EP96YA;64_at_5#X-"B @
M("!V96-T/'1Y<&5N86UE(&)I;F]P/"!4+"<J)RQ4/CHZ='EP93X-"B @("!C
M<F]S<U]P<F]D=6-T* T*(" @(" @("!V96-T/%0^(&-O;G-T("8@;&AS+ T*
M(" @(" @("!V96-T/%0^(&-O;G-T("8@<FAS#0H@(" @*7L-"B @(" @(" @
M=F5C=#Q"3T]35%]465!%3T9?5%!,*"!4*"D@*B!4*"DI/B!R97-U;'0H#0H@
M(" @(" @(" @("!L:',N>2 J(')H<RYZ("T@;&AS+GH@*B!R:',N>2P-"B @
M(" @(" @(" @(&QH<RYZ("H@<FAS+G@@+2!L:',N>" J(')H<RYZ+" -"B @
M(" @(" @(" @(&QH<RYX("H@<FAS+GD@+2!L:',N>2 J(')H<RYX#0H@(" @
M(" @("D[#0H@(" @(" @(')E='5R;B!R97-U;'0[#0H@(" @?0T*(" @( T*
K?7U]+R]B;V]S=#HZ9V5O;65T<GDZ.G1H<F5E7V0-"@T*#0HC96YD:68-"@``
`
end