PDA

View Full Version : Could a multidimensional array be viewed as a matrix?

MorphingDragon
Sep 8, 2010, 06:16 AM
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?

Hawkeye411
Sep 8, 2010, 06:18 AM
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.

Doesn't arr[2][2] = 8?

robbieduncan
Sep 8, 2010, 06:48 AM
Is it possible to get multidimensional NSArray without nesting an array within an array?

No

MorphingDragon
Sep 8, 2010, 07:26 AM
Doesn't arr[2][2] = 8?

Arrays start counting at 0.

arr[2] is the 3rd member.

AlmostThere
Sep 8, 2010, 07:42 AM
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.

MorphingDragon
Sep 8, 2010, 09:58 AM
Also, matrix notation generally starts counting at 1.

I know, but array notation starts at 0. ;)

That wiki page was interesting though.

lee1210
Sep 8, 2010, 10:03 AM
I know, but array notation starts at 0. ;)

Just use fortran, it starts at 1. Unless you want it to start somewhere else...

-Lee

balamw
Sep 8, 2010, 10:14 AM
Just use fortran, it starts at 1.
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

MorphingDragon
Sep 8, 2010, 10:38 AM
MorphingDragon, do you intend to do matrix operations/linear algebra on your 2D arrays? Or are they containers for some other kind of data?

Yes, this is another part of my arbitrary University assignment to make classes/methods for Vectors and Matrices.

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

Matrices -
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.

Sydde
Sep 8, 2010, 11:39 AM
Slightly OT:
Is it possible to get multidimensional NSArray without nesting an array within an array?

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).

chown33
Sep 8, 2010, 01:15 PM
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]?
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.

MorphingDragon
Sep 8, 2010, 07:49 PM
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.

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)

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).

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; ?

chown33
Sep 8, 2010, 08:28 PM
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)

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.

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; ?
Looks like programming questions to me.

Yes. Yes. Yes. (Assuming appropriate type declarations for the variables, of course.)

MorphingDragon
Sep 8, 2010, 08:36 PM
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.

I come from a commonwealth country, it'll most likely be british notation.

Looks like a programming question to me.

I asked two questions one main one and one sort of OT one.

lee1210
Sep 8, 2010, 08:37 PM
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

MorphingDragon
Sep 8, 2010, 11:12 PM
Pointers to pointers is a pretty common way to implement dynamically allocated multidimensional arrays.

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.

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.

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

A[rows][columns]

autorelease
Sep 9, 2010, 03:08 AM
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:
[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:
[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.

Sander
Sep 9, 2010, 05:02 AM
Is this an Objective-C assignment? (If so, interesting that this is being taught at an university.)

MorphingDragon
Sep 9, 2010, 05:04 AM
Is this an Objective-C assignment? (If so, interesting that this is being taught at an university.)

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.

SidBala
Sep 9, 2010, 11:52 AM
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

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!

MorphingDragon
Sep 9, 2010, 12:24 PM
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.

Yes but separate classes make the distinction between them clear, and it help avoids silly things like -

aMatrixAsAVector.dotProduct(aMatrix);

There, I have just outlined your project. Good luck!

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#.

SidBala
Sep 9, 2010, 02:12 PM
Yes but separate classes make the distinction between them clear, and it help avoids silly things like -

aMatrixAsAVector.dotProduct(aMatrix);

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:

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.

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#.

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.

MorphingDragon
Sep 9, 2010, 03:13 PM
Whatever language you choose, the basic concepts are all the same.

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

SidBala
Sep 9, 2010, 04:29 PM