Two-Dimensional Dynamic Arrays

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gianni Mariani

    #46
    Re: Two-Dimensional Dynamic Arrays

    Axter wrote:
    ....[color=blue]
    > The above link has two classes. One which I'm the author of, and the
    > second class which allows you to use both [][] and operator() method.
    > I don't think it's a good idea to have both methods in a class, but
    > some developers may find this method more acceptable.[/color]

    I thought about putting both () and [][] in a class and I came to the
    conclusion that you don't want to encourage both methods. You really
    only want one, if someone is desperate for a (x,y) method, they can
    easily add one.


    Comment

    • jrp

      #47
      Re: Two-Dimensional Dynamic Arrays

      Are there any additional issues with extending this code to THREE
      dimensions?

      Comment

      • Gianni Mariani

        #48
        Re: Two-Dimensional Dynamic Arrays

        jrp wrote:[color=blue]
        > Are there any additional issues with extending this code to THREE
        > dimensions?
        >[/color]

        For dynamically sized matrix classes of three or more dimensions, if you
        want to use a [][][] syntax, you need to use a proxy object as a result
        of the first operator[] calls > 2.


        Comment

        • roberts.noah@gmail.com

          #49
          Re: Two-Dimensional Dynamic Arrays


          Axter wrote:
          However, objects appear to be better suited for the () syntax[color=blue][color=green]
          > > for reasons that have already been gone over several times ->[/color]
          > I completely disagree. I've only read contrived justifications for
          > using () syntax, that have nothing to do with generic programming, or
          > with 99.99% of C++ development.
          > Example:
          > Previous Post:[color=green][color=darkred]
          > >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>
          > >>Tell me then, how exactly is the compiler going to hide the internal representiation of
          > >>the matrix when you have exposed it with the first [] operator??!!
          > >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>[/color][/color]
          >
          > 99.99% of developers would never ever need to get the internal
          > representation of the matrix, and would never need to change col for
          > row within the matrix.[/color]

          Uh...the problem I have cited over and over and over again with all but
          one implementation of the operator[][] method of matrix/2d array has
          been that the internal rep is already exposed; there are a hundred
          things wrong with this and I have reiterated some of these several
          times. I don't know why you bring up the point that 99.99% of
          developers don't need to access the internals of the matrix class...I
          would make this a stronger point and say that 100% of developers do not
          need to access the internals of a matrix class. Those that need more
          performance than they can get through the interface should use a
          different class or maybe they even need to use C arrays period and toss
          out all the "OO Overhead".

          You keep running around in circles missing the point completely. Now
          you are just talking nonsense - well the statement you made makes
          sense, just not in the context of the argument and certainly not
          *against* anything I have said, in fact it only reinforces my points.

          Comment

          • roberts.noah@gmail.com

            #50
            Re: Two-Dimensional Dynamic Arrays


            Gianni Mariani wrote:[color=blue]
            > jrp wrote:[color=green]
            > > Are there any additional issues with extending this code to THREE
            > > dimensions?
            > >[/color]
            >
            > For dynamically sized matrix classes of three or more dimensions, if you
            > want to use a [][][] syntax, you need to use a proxy object as a result
            > of the first operator[] calls > 2.[/color]

            Why not just return &&array[x]

            Notice how the () syntax keeps encapsulation without the need of an
            adapter even with 2d and with 3d still doesn't need one.

            Comment

            • Gianni Mariani

              #51
              Re: Two-Dimensional Dynamic Arrays

              roberts.noah@gm ail.com wrote:
              [color=blue]
              >
              > Why not just return &&array[x]
              >
              > Notice how the () syntax keeps encapsulation without the need of an
              > adapter even with 2d and with 3d still doesn't need one.
              >[/color]

              plonk

              Comment

              • roberts.noah@gmail.com

                #52
                Re: Two-Dimensional Dynamic Arrays


                Axter wrote:
                [color=blue]
                > I forgot to mention that your wrapper class also fails to have a GetCol
                > and GetRow function.[/color]

                You are of course right and that is an obvious problem except for one
                thing. The presented class is an adapter to provide () syntax when
                using a C array. Since someone that needs that adapter is already
                using a C array outside of a class and so is tracking the dimensions
                already the GetCol and GetRow functions would be redundant. However,
                since the addition of these functions is relatively straight forward
                and could come of use, possibly, their ommision is probably a mistake.

                As you also state, I could have also improved it to also adapt vectors.
                [color=blue]
                > Also check out another CodeGuru STL FAQ:
                > http://www.codeguru.com/forum/showth...hreadid=297838
                >
                > The above link has two classes. One which I'm the author of, and the
                > second class which allows you to use both [][] and operator() method.
                > I don't think it's a good idea to have both methods in a class, but
                > some developers may find this method more acceptable.[/color]

                Decent:


                Still has a dependency that could be removed. It could be more
                abstract. No matter how you slice it the interface still spells out a
                particular alignment. This is forgivable but with op() that problem
                doesn't exist so that is still +1 for op().

                The reason this version is better is that because it returns a vector
                reference instead of pointer to a memory chunk; therefor the class is
                protected from clients trying to overwrite into a second row on
                accident. The vector interface is sufficient to offer protection in
                this area and it still retains a great deal of efficiency. Basically
                the vector is acting a lot like the previously supplied "proxy".

                On the other hand, this class doesn't seem that necessary. Why not
                just use the vector<vector<> > in the open? The only really nice thing
                this class offers is the sizing of the internal vectors. Makes me
                wonder if the constructor shouldn't just call resize.

                The other link you have above... The first class is no good; it is the
                same trash you already posted in fact - why are you wasting everyone's
                time like that? Do you think that by looking at it somewhere else it
                will change the problems inherent in its design??

                Second implementation also has problems but is several degrees better
                than yours. I would remove the op[]'s. The iterator idea was great
                but could have been expanded to include columns. getRow is dangerous
                and has the same problems as op[] - I think it would be better to stay
                with the iterator idea and toss getRow or just make it return an
                iterator.

                Comment

                • roberts.noah@gmail.com

                  #53
                  Re: Two-Dimensional Dynamic Arrays


                  Gianni Mariani wrote:[color=blue]
                  > roberts.noah@gm ail.com wrote:
                  >[color=green]
                  > >
                  > > Why not just return &&array[x]
                  > >
                  > > Notice how the () syntax keeps encapsulation without the need of an
                  > > adapter even with 2d and with 3d still doesn't need one.
                  > >[/color]
                  >
                  > plonk[/color]

                  Coward.

                  Comment

                  • roberts.noah@gmail.com

                    #54
                    Re: Two-Dimensional Dynamic Arrays


                    roberts.noah@gm ail.com wrote:
                    [color=blue]
                    > Decent:
                    > http://www.codeguru.com/forum/showth...hreadid=231046[/color]

                    Come to think of it, I like it less now that I think on it....not for a
                    real 2d matrix anyway - or anything where rows should be the same
                    length. Reason is simple:

                    T t();

                    mtx[x].push_back(t);

                    This is ok, since the class doesn't stop you from doing it (and can't)
                    but it's rather ugly. The purpose of this class seems pretty straight
                    forward in that the above call shouldn't be allowable even though it
                    is. This is a pretty tricky problem though and I'm not surprised it
                    slipped past the developer (maybe it didn't and they decided to live
                    with it). The answer is of course that some sort of policy is created
                    that is self enforced by developers...so meone usually breaks that kind
                    of policy though. Any client that used the iterator interface or based
                    its operation on .size() could break down with the above, buggered mtx.

                    It's a point against it anyway. You can do the same with
                    vector<vector<> > but at least that isn't pretending to be rectangular.
                    The single chunk of memory solution also seems to have the possibility
                    at least of being more efficient....le ss redirections.

                    Of course this is also caused by an encapsulation issue. I tricked
                    myself into thinking it would be ok in this case. Just goes to show I
                    guess.

                    You could fix this by returning a class that *contains* the vector (or
                    non-public inheritance) that did not provide the functions that would
                    pose the problem. This works because it fixes the encapsulation issue.
                    If you thought ahead enough this returned class could be based on
                    something abstract that could be implemented in any number of
                    manners...meani ng the vectors wouldn't even have to be there at all.

                    In the end it is similar to the previous example and I still think the
                    () interface still ends up providing the same benefits with less work.

                    Comment

                    • jrp

                      #55
                      Re: Two-Dimensional Dynamic Arrays

                      I can see both sides of the argument so far, but would like to explore
                      a bit further real world usage and performance of such classes,
                      including with"legacy" code.

                      The first thing that most of the above examples would need is const
                      versions of many of the operations; the second is that it needs to be
                      possible to use an aligned malloc to allocate storage to get the
                      benfits of vectorization. Finally, it needs to be possible to allocate
                      the memory so that there is no aliasing (or do so via a restrict
                      decoration).

                      To be more specifif, suppose that I want to build a system of 3d
                      numeric objects (cubes) that can be sliced into 2 and 1d objects
                      (planes, rows), and those 2d objects can also be sliced into 1d rows.
                      And I want to be able to present those rows to legacy C routines that
                      expect C arrays and lengths. I also want to be able to do things like

                      acube = 0;
                      acube[nplane] = 0;

                      aplane[nrow] =0;

                      acube[nplane] = aplane;

                      and present an acube[nplane] to a routine as a const Plane& parameter.

                      (using () if necessary).

                      As I understand it, the original intention was for valarray + slice to
                      do this job but that seems to be harder to achieve efficiently and
                      usable.

                      There are those that say use Blitz++, or boost::multi_ar ray, or
                      stlorg::fixed_a rray. These are heavy packages, yet none of them seems
                      to provide a drop-in replacement for the ugly but functional
                      vector<vector<v ector>>> and [][][].


                      It would be helpful to discuss this on the basis of some concrete
                      candidate classes such as those earlier in the thread so that we can
                      test performance / applicability. For example, are address
                      dereferences slower than int multiplications ?

                      Comment

                      • Axter

                        #56
                        Re: Two-Dimensional Dynamic Arrays


                        roberts.noah@gm ail.com wrote:[color=blue]
                        > roberts.noah@gm ail.com wrote:
                        >[color=green]
                        > > Decent:
                        > > http://www.codeguru.com/forum/showth...hreadid=231046[/color]
                        >
                        > Come to think of it, I like it less now that I think on it....not for a
                        > real 2d matrix anyway - or anything where rows should be the same
                        > length. Reason is simple:
                        >
                        > T t();
                        >
                        > mtx[x].push_back(t);
                        >
                        > This is ok, since the class doesn't stop you from doing it (and can't)
                        > but it's rather ugly. The purpose of this class seems pretty straight
                        > forward in that the above call shouldn't be allowable even though it
                        > is. This is a pretty tricky problem though and I'm not surprised it
                        > slipped past the developer (maybe it didn't and they decided to live
                        > with it). The answer is of course that some sort of policy is created
                        > that is self enforced by developers...so meone usually breaks that kind
                        > of policy though. Any client that used the iterator interface or based
                        > its operation on .size() could break down with the above, buggered mtx.
                        >
                        > It's a point against it anyway. You can do the same with
                        > vector<vector<> > but at least that isn't pretending to be rectangular.
                        > The single chunk of memory solution also seems to have the possibility
                        > at least of being more efficient....le ss redirections.
                        >
                        > Of course this is also caused by an encapsulation issue. I tricked
                        > myself into thinking it would be ok in this case. Just goes to show I
                        > guess.
                        >
                        > You could fix this by returning a class that *contains* the vector (or
                        > non-public inheritance) that did not provide the functions that would
                        > pose the problem. This works because it fixes the encapsulation issue.
                        > If you thought ahead enough this returned class could be based on
                        > something abstract that could be implemented in any number of
                        > manners...meani ng the vectors wouldn't even have to be there at all.
                        >
                        > In the end it is similar to the previous example and I still think the
                        > () interface still ends up providing the same benefits with less work.[/color]

                        I know you among others, don't seem to see a syntax problem with using
                        operator(), but here's a small example of how using operator() instead
                        of [][] can make your code ambiguous.
                        CMatrix arr(12, 34);
                        ..... lost of other code ....
                        ..... losts more code ....
                        int x = arr(1, 3);// Is arr a function, or a class????

                        If arr is far removed from it's declaration, a normal assumption would
                        be to think arr is a function, and the above line of code is calling a
                        global arr function.

                        int x = arr[1][3]; // This is much less ambiguous, and easy to identify
                        arr as an array

                        Using operator() for arrays makes the code more confusing, and harder
                        to read and maintain, where as using [][] is straight forward, and very
                        easy to pick what's going on in above line of code.
                        Why use ambiguous syntax when you don't have to?????

                        Comment

                        • Kai-Uwe Bux

                          #57
                          Re: Two-Dimensional Dynamic Arrays

                          Axter wrote:
                          [color=blue]
                          >[/color]
                          [snip][color=blue]
                          > I know you among others, don't seem to see a syntax problem with using
                          > operator(), but here's a small example of how using operator() instead
                          > of [][] can make your code ambiguous.
                          > CMatrix arr(12, 34);
                          > .... lost of other code ....
                          > .... losts more code ....
                          > int x = arr(1, 3);// Is arr a function, or a class????
                          >
                          > If arr is far removed from it's declaration, a normal assumption would
                          > be to think arr is a function, and the above line of code is calling a
                          > global arr function.
                          >
                          > int x = arr[1][3]; // This is much less ambiguous, and easy to identify
                          > arr as an array
                          >
                          > Using operator() for arrays makes the code more confusing, and harder
                          > to read and maintain, where as using [][] is straight forward, and very
                          > easy to pick what's going on in above line of code.
                          > Why use ambiguous syntax when you don't have to?????[/color]

                          To me, it seems that the problem in this code does not arise from
                          overloading operator(). It arises from choosing a poor variable name. C++
                          has the feature of allowing for function objects. Therefore, any expression
                          like

                          identifier( arg_1, arg_2, arg_3 );

                          could be a function call, creation of a temporary, invoking operator(), or
                          maybe even more. The way to cope with this "ambiguity" is not to ban
                          overloading operator() but to choose identifiers wisely so that an object
                          of type CMatrix can be recognized as such.


                          Best

                          Kai-Uwe Bux

                          Comment

                          • Axter

                            #58
                            Re: Two-Dimensional Dynamic Arrays


                            Kai-Uwe Bux wrote:[color=blue]
                            > Axter wrote:
                            >[color=green]
                            > >[/color]
                            > [snip][color=green]
                            > > I know you among others, don't seem to see a syntax problem with using
                            > > operator(), but here's a small example of how using operator() instead
                            > > of [][] can make your code ambiguous.
                            > > CMatrix arr(12, 34);
                            > > .... lost of other code ....
                            > > .... losts more code ....
                            > > int x = arr(1, 3);// Is arr a function, or a class????
                            > >
                            > > If arr is far removed from it's declaration, a normal assumption would
                            > > be to think arr is a function, and the above line of code is calling a
                            > > global arr function.
                            > >
                            > > int x = arr[1][3]; // This is much less ambiguous, and easy to identify
                            > > arr as an array
                            > >
                            > > Using operator() for arrays makes the code more confusing, and harder
                            > > to read and maintain, where as using [][] is straight forward, and very
                            > > easy to pick what's going on in above line of code.
                            > > Why use ambiguous syntax when you don't have to?????[/color]
                            >
                            > To me, it seems that the problem in this code does not arise from
                            > overloading operator(). It arises from choosing a poor variable name. C++
                            > has the feature of allowing for function objects. Therefore, any expression
                            > like[/color]

                            I agree, but you find too many developers that will use short
                            initialized names, that may be perfectly clear to them, but complete
                            ambiguous to the next developer that has to maintain his/her code.
                            I'm not advocating a ban on using operator(). I just don't think using
                            it in place of [][] is appropriate, and leads to ambiguous code.

                            Comment

                            • roberts.noah@gmail.com

                              #59
                              Re: Two-Dimensional Dynamic Arrays


                              jrp wrote:
                              [color=blue]
                              > To be more specifif, suppose that I want to build a system of 3d
                              > numeric objects (cubes) that can be sliced into 2 and 1d objects
                              > (planes, rows), and those 2d objects can also be sliced into 1d rows.
                              > And I want to be able to present those rows to legacy C routines that
                              > expect C arrays and lengths. I also want to be able to do things like
                              >
                              > acube = 0;
                              > acube[nplane] = 0;[/color]

                              I take it that the above is filling with 0's? I see the need for such
                              an operation but I am not sure I like the syntax. You could also be
                              meaning (especially in the top instance) assign to this cube with a
                              cube with no dimensions.[color=blue]
                              >
                              > aplane[nrow] =0;
                              >
                              > acube[nplane] = aplane;[/color]

                              I can also see the need for this operation but I think the syntax is
                              flawed here as well. Do you mean X, Y, or Z axis plane? Functional
                              syntax would be better here I think. Could be a single function
                              getPlane(x, axis) or three seperate for each axis.[color=blue]
                              >
                              > and present an acube[nplane] to a routine as a const Plane& parameter.[/color]

                              Or even a non const. Seems you would also want to be able to pass
                              planes, rows, or individual items to manipulators.
                              [color=blue]
                              > It would be helpful to discuss this on the basis of some concrete
                              > candidate classes such as those earlier in the thread so that we can
                              > test performance / applicability. For example, are address
                              > dereferences slower than int multiplications ?[/color]

                              I would add a requirement. You must be able to create a new class that
                              stores its data in a different manner, possibly col mjr form but could
                              be anything, that will work as a parameter to any function or algorithm
                              that expects the designed class.

                              I'll play but it will take a while as time is an issue.

                              Comment

                              • jrp

                                #60
                                Re: Two-Dimensional Dynamic Arrays

                                Thanks. I won't quibble about the syntax (although there is a logic to
                                it). What interests me is ((empirical) relative performance, including
                                vectorizability ) and completeness: so missing const versions of
                                operators are an issue, and may help to tip the balance for those
                                interested in clutter / complexity.
                                [color=blue]
                                > I'll play but it will take a while as time is an issue.[/color]

                                Thanks. Likewise. Happy to contribute, if necessary.

                                Comment

                                Working...