Could a multidimensional array be viewed as a matrix?

Discussion in 'Mac Programming' started by MorphingDragon, Sep 8, 2010.

  1. macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #1
    Could a multidimensional array be viewed as a matrix of numbers? I've gotten to a point where I really need to use 2D arrays now, but I'm having trouble visualizing them and making the mathematical connection which is making debugging a pain.

    Say A is a 3x3 matrix and "arr" is a 2D array.

    A=
    [1 2 3]
    [4 5 6]
    [7 8 9]

    So would:
    arr[0][0] = 1?
    arr[0][1] = 2?
    arr[2][1] = 8?
    arr[1][1] = 5?
    (A)33 = arr[2][2]?

    etc.

    Slightly OT:
    Is it possible to get multidimensional NSArray without nesting an array within an array?
     
  2. macrumors 68000

    Hawkeye411

    Joined:
    Jun 6, 2007
    Location:
    Canada EH!!!
    #2
    Doesn't arr[2][2] = 8?
     
  3. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #3
    No
     
  4. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #4
    Arrays start counting at 0.

    arr[2] is the 3rd member.
     
  5. macrumors 6502a

    #5
    If I understand the question correctly, yes.

    But you probably want to read this page http://en.wikipedia.org/wiki/Row-major_order and bear in mind the domain you are working in (for example, much linear algebra code is written in Fortran and different C bindings may or may not perform the appropriate transformation ... it has been a while. I think veclib does but other implementations don't).

    Also, matrix notation generally starts counting at 1.

    Lots of tiny gotchas to be aware of.
     
  6. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #6
    I know, but array notation starts at 0. ;)

    That wiki page was interesting though.
     
  7. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    Just use fortran, it starts at 1. Unless you want it to start somewhere else...

    -Lee
     
  8. Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #8
    MATLAB too. ;)

    MorphingDragon, do you intend to do matrix operations/linear algebra on your 2D arrays? Or are they containers for some other kind of data?

    B
     
  9. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #9
    Yes, this is another part of my arbitrary University assignment to make classes/methods for Vectors and Matrices.

    Requirements:
    Vectors -
    Add/Subtract vectors etc
    Dot/Cross product
    Find area/volume of parallelogram/ppped formed.

    Matrices -
    Addition/Subtraction/Multiplication
    Find Inverse/Discriminant

    There's "extra credit" (Which turns out the lecturer buys you a chocolate bar ¬_¬) for making the methods and classes scale to different sizes, so I've been trying to make them scale by using arrays. I have the classes working with fixed sized vectors and arrays.

    I'm going to go out on a limb and say that the University is making sure we have the maths knowledge for computer graphics, physics processing for papers next year etc.
     
  10. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #10
    It is possible if you calculate your indices manually, as in ( yIndex * arrayWidth ) + xIndex; this would work for any array depth, just as it would for any depth of a C array, but it would probably fail spectacularly if the NSArray was not absolutely full. One possible alternative would be a NSPointerArray, which can be presized and can contain null elements - but at that point, you might as well use a C array unless you have encoding concerns (pointer size/endian-ness).
     
  11. macrumors 603

    Joined:
    Aug 9, 2009
    #11
    Given what you've posted, then arr is uninitialized. So if your questions use '=' as the symbol meaning "compares equal to", then the answer is "Maybe", because arr's initial contents are undefined.

    If your questions use '=' as the assignment symbol, then they are assignment statements, not questions.

    And I have no idea how to interpret the expression (A)33 on the left-hand side of the last statement/question.


    Also remember that NSArray can only hold objects. It can't hold fundamental types like int, long, or double. To do that, you must wrap the value in an object type, like NSNumber. This adds complexity, and may incur a significant performance cost, depending on what you're doing with the arrays.
     
  12. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #12
    Its not a programming question chown, its just pseudo code and mathematical notation to ask a theory question. If you don't understand mathematical notation like (A)33 then don't worry. (Which is FYI, 3rd row and 3rd column of Matrix A)

    Can C arrays hold pointers? Could you just give the pointer itself to an object in memory? (I'm not near a computer with GCC or clang atm)

    id aPointer;
    arr[0] = &aPointer; ?
     
  13. macrumors 603

    Joined:
    Aug 9, 2009
    #13
    I've seen several notations for matrix elements, such as M(i,j), M[i,j], but never (M)ij. I can't help wondering what happens when rows or columns exceeds 9.


    Looks like programming questions to me.

    Yes. Yes. Yes. (Assuming appropriate type declarations for the variables, of course.)
     
  14. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #14
    I come from a commonwealth country, it'll most likely be british notation.


    I asked two questions one main one and one sort of OT one.
     
  15. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #15
    http://forums.macrumors.com/showthread.php?t=844474
    Pointers to pointers is a pretty common way to implement dynamically allocated multidimensional arrays.

    Row 11 column 1 and row 1 column 11 will be a bitch to tell apart with that notation. I just had to fix some code that didn't use a delimiter, it is not fun.

    -Lee
     
  16. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #16
    Thats... complex. :eek:

    Though this shouldn't be as complex as sorting strings in a multiarray.

    I'll try study it over the weekend and extract any useful bits.



    I don't think it will be that difficult if I treat the notation like normal Matrix notation.

    A[rows][columns]
     
  17. macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #17
    It seems like this is being made much more complicated than it has to be.

    You don't need NSArrays, you don't need pointers to pointers.

    Just a dynamically allocated, one-dimensional C array (created with malloc), and a width and height parameter. (number of columns, number of rows)

    Like Sydde said, it's easy to convert multidimensional coordinates to a linear index:
    Code:
    [element at row N, column M = elements[numColumns*N + M]
    You don't get to use nice multidimensional array syntax, so just write accessor/modifier methods:
    Code:
    [myMatrix elementAtRow:n column:m];
    [myMatrix setElementAtRow:n column:m to:x];
    As an aside, when you use an array of pointers to arrays, you get what's called a two-dimensional "ragged array"; one where all rows don't have to have the same number of columns. This is overkill for a simple matrix class though.
     
  18. macrumors 6502

    Joined:
    Apr 24, 2008
    #18
    Is this an Objective-C assignment? (If so, interesting that this is being taught at an university.)
     
  19. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #19
    This paper is taught in C#, but we can submit the assignments in any language.

    The university teaches us Java and C# (and if you're doing software engineering assembly for x86) explicitly, we're expected to learn any other languages by ourselves and in most papers we get to choose what language we use.
     
  20. macrumors 6502a

    Joined:
    Jun 27, 2010
    #20
    If you can use C# then use C#. Also, if you are not comfortable with pointers, then don't use them. Use dynamic collection classes provided by the std lib in C++ and the Systems.Collections namespace in C#. They are much safer and a lot cleaner. Almost no one ever uses malloc'ed arrays directly anymore. Unless if it was performance code.

    And never use multidimensional dynamic arrays unless you really have to. They are really messy and can lead to many problems and buggy code. Use 1D array and transform the 2D coordinates to 1D.

    Create a common class for both vectors and matrices called VecMat or something else. Vectors are just matrices with the length in one dimension = 1.

    This class should contain a C# ArrayList or equivalent to hold the values. This is a 1-D array. Make the class contain variables height and width.

    Setup a constructor for the class so you can do:

    VecMat myMat = New VecMat( 3, 2,
    54, 23,
    65, 32,
    49, 93);

    VecMat myVec = new VecMat(3,1,
    10,
    65,
    93);

    Where 3,2 and 3,1 specify the size and the rest of the parameters are the values that go into the matrix. Use variable length parameters to accept an uncertain number of parameters into your constructor.

    Also create a At(x,y) function or overload the [][] operator to get:

    myMat.At(1,1) or
    myMat[1][1]

    To get the values at 1,1 etc

    Now overload the addition, multiplication, subtraction operators to do things like:

    myVec = (myMat1 + myMat2) * myVec1 - myMat3

    Throw exceptions when they cant be multiplied or added.

    Remember that by making the vectors and matrices the same class, you can very easily multiply vectors with matrices and matrices with other matrices by just defining one overloaded operator.

    Now overload other operators of your choice to define dot products and cross products.

    If you want extra credit, use templates in your matrix class. Now you can multipy a matrix of anything. ints, floats, even complex numbers!

    If you really want to go overboard with the extra credit, make the number of dimensions scalable too, so you can operate on multidimensional tensors!

    There, I have just outlined your project. Good luck!
     
  21. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #21
    Yes but separate classes make the distinction between them clear, and it help avoids silly things like -

    aMatrixAsAVector.dotProduct(aMatrix);

    I've already done the compulsory part of the assignment, changing the classes to scale is the extra credit.

    ---

    This is just my preference but I do my assignments in C and Obj-C/C++ (Depending on the assignment if it needs OOP). C# is a nice language (I prefer it over Java), but all that syntax sugar is why I don't use it for Uni projects. I want to learn how the actual logic behind it works, spending the time to get it work in something like C will be more beneficial than getting it to work in a sugar coated language like C#.
     
  22. macrumors 6502a

    Joined:
    Jun 27, 2010
    #22
    I would STRONGLY disagree. Defining seperate classes just to "make the distinction between them clear" is a very bad reason to do so.

    The fundamental reason why you want them to be same class is because they are the same. You can share the operators among them. Remember that you can multiply vectors to matrices, matrices to vectors and matrices to matrices and vectors to vectors.

    You will need to define 4 operators to accomplish these. But with common class, you can just define one overloaded operator for every operation. It makes the code look a lot cleaner and it will allow you to scale it very easily.

    This approach is very common in Matlab and many other math suites. They don't differentiate between vectors and matrices. Vectors are just matrices with one row/column.

    The error case you mentioned,

    aVectorAsAMatrix DOT aMatrix

    is no different from:

    aVectorOfOneSize DOT aVectorOfaDifferentSize

    Both the above operations fail because of their non matching sizes. So differentiating the classes wouldn't help since you would still have to error out with the sizes of two vectors are different.

    The two operations would exception out in the same way:

    if(LeftOperand.isVector && rightOperand.isVector && leftOperand.Size == rightOperand.Size)
    ---transpose the leftOperand into a row vector and multiply with the rightOperand as a column vector.
    ELSE
    ---throw exception

    .isVector does nothing but check if one of the dimensions is = 1 and .Size is a struct that holds x and y dimensions.

    This works the right way for vectors and matrices.

    Hence there is no reason to unnecessarily duplicate the classes.

    Whatever language you choose, the basic concepts are all the same. The more complex concepts however, are not available in C. For OOP you would need to go C++ as is not available in C. C# offers even more with reflection etc.
     
  23. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #23
    I wasn't talking about concepts, I was talking about the underlying logic of programs that syntax sugar hide. Please read.

    Oh and FTR, you can do OO (and thus reflection) with C.
    http://www.planetpdf.com/codecuts/pdfs/ooc.pdf
     
  24. macrumors 6502a

    Joined:
    Jun 27, 2010
    #24
    Your "FTR" statement is very common knowledge. You can implement everything directly in opcodes too. There is a reason why people don't do that. If you have to ask on a forum about how to use dynamic arrays, you are obviously far from understanding implementation details behind it.

    No I am not going to "read". You asked for help. I gave it. Now if you want to be thankless about it, then fine. But don't tell me to "read". It is not like it's my job.

    Got it?
     

Share This Page