Multi dimensional arrays in Objective-C

Discussion in 'Software Programming & Web Scripting' started by Viro, Mar 23, 2005.

  1. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    Simple question for those familiar with Objective-C. What are my options for using multi-dimensional arrays in Objective-C?
     
  2. lurk

    lurk Mitä?

    Joined:
    Mar 30, 2002
    Messages:
    2,088
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Land o' skeeterz
    Identical to C and Java. How is that for a non answer? Really it depends on what you mean by "array" do you mean a bunch of things in consecutive memory location a la C, or do you mean an instance of NSArray?
     
  3. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    That'll teach me to post a 12:30 am :).

    I meant multidimensional arrays of primitives, particularly doubles. In C, you can do it with a large array and simulate it with various offsets. Problem is, you need to code lots.

    I was hoping for a simpler solution in Objective-C, sorta like NSArray, except NSArray seems to deal with objects while I'm interested in primitives. You might be able to wrap primitives in objects but performance suffers and I don't want that. Is there something like NSArray for primitives? Or do I have to write one myself?
     
  4. cfleck

    cfleck tired

    Joined:
    Nov 9, 2002
    Messages:
    825
    Likes Received:
    2
    Trophy Points:
    0
    Location:
    Indianapolis
    Actually in c you can make an array of pointers to array and thus have 2 dimensional arrays. You needn't fiddle with offsets.
     
  5. Lycander

    Lycander Registered

    Joined:
    Jun 25, 2003
    Messages:
    700
    Likes Received:
    0
    Trophy Points:
    0
    If you can squeeze STL in and use objective-C++

    Code:
    #include <vector>
    using namespace std;
    
    typedef vector <double> VDOUBLE;
    
    int main()
    {
       vector<VDOUBLE> vecvec;  // this is the 2D array
    
       VDOUBLE v1( ... );  // initialize it here or populate it with data later
       VDOUBLE v2( ... ); // same as above
    
       vecvec.push_back( v1 );  // add the array of doubles to the end
       vecvec.push_back( v2 );  // same as above
    
       // VDOUBLE is your new data type. Continue making new single dimension
       // arrays and add them to vecvec, the 2D array
    
       // Getting values out of the 2D array:
       for(int i=0; i<vecvec.size(); i++)
       {
          for(int j=0; j<vecvec[i].size(); j++)
          {
             cout << vecvec[i][j] << "\n";
          }
       }
       return 0;
    }
     
  6. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    I've thought of that, but you lose some speed though, since the array is no longer contiguous and there is less of a chance that the whole array fits into cache :).
     
  7. cfleck

    cfleck tired

    Joined:
    Nov 9, 2002
    Messages:
    825
    Likes Received:
    2
    Trophy Points:
    0
    Location:
    Indianapolis
    May I ask what it is that you are doing that you are shooting for such cache use?
     
  8. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    I'm currently working with chaotic temporal neural networks, that have an internal state that's based on a modified Rossler system (for the chaos). It's pretty bleeding edge at the moment and I don't think there is any other research group working on it.

    I'm doing a lot of numerical analysis of the neural nets I build and various other experiments to understand the models I'm working with. Most of them are written in MATLAB and this has been very slow. Currently, I'm in the process of re-implementing everything in C and thus far have seen a speed up in the region of 100x. I'm keen on having everything in the cache as far as possible since memory accesses are heavily penalized on most machines apart from those lovely Opterons that have an on die memory controller ;).

    Objective-C comes in because I'd like to try new stuff :). It's a great opportunity to learn the language and it's a chance to get familiar with Cocoa. Plus, if I make mistakes this new system, I've still got my old system written in MATLAB to validate it against so there's no worry that it'll impact my research too much. It also doesn't hurt that I'm on holiday at the moment and want something to do while my fiancee is away with her parents.

    But this is all tangential to the topic at hand...
     
  9. lurk

    lurk Mitä?

    Joined:
    Mar 30, 2002
    Messages:
    2,088
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Land o' skeeterz
    In this case you have to do it the C way. There is no support for anything related to primitives that is specific to Objective-C it all just relies on C for that. So you just have to use the foo[1][4][3] style notation. You do not have to compute any offsets yourself though, the compiler should do it for you with the right declarations.
     
  10. Aleran

    Aleran Registered

    Joined:
    Dec 12, 2002
    Messages:
    23
    Likes Received:
    0
    Trophy Points:
    0
    Damn, Neural Nets is the field I really want to get into, though I haven't even scratched the surface of the field as I've only read ch. 1 in a couple books on it I have and don't have the time to read more due to having my actual comp sci classes (I'll try to take a class on neural nets my senior year). :(

    Any way as per your question I would agree with Lurk, just define a C matrix as its easier than using an offset (not that its a big deal to use a offset, but its still easier)

    double myMatrix[num_rows][num_cols];
     
  11. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    Problem with the C definitions given is that they're stack based. Works fine for most small arrays, but when you start using large arrays, you need them to be allocated from the heap. Hence, the need to malloc() or calloc() your arrays.

    Anyhow, I'm currently using a 1D array, and simulating my own offsets. It's the way the GNU Scientific library does it, and it's the way most people in the field do it. Here is an example for anyone who might search the forums and wonder how to do the exact same thing :).

    Code:
    /*Array2D.h*/
    #ifndef __ARRAY_2D
    #define __ARRAY_2D
    
    typedef struct Array2D {
    	double *data;
    	int w, h;
    }Array2D;
    
    Array2D *a2d_create(int h, int w);
    void a2d_destroy(Array2D *a);
    double a2d_get(Array2D *a, int row, int col);
    void a2d_set(Array2D *a, int row, int col, double d);
    #endif
    
    /*************Array2D.c*******************/
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <assert.h>
    
    #include "array2d.h"
    
    
    Array2D *a2d_create(int h, int w) {
    	Array2D *a = (Array2D *)calloc(1, sizeof(*a));
    	assert(a != NULL);
    	
    	a->w = w;
    	a->h = h;
    	a->data = (double *)calloc(w * h, sizeof(*a->data));
    	assert(a->data != NULL);
    	
    	return a;
    		
    }
    
    void a2d_destroy(Array2D *a) {
    
    	if(a != NULL) {
    		if(a->data != NULL)
    			free(a->data);
    		free(a);
    	}
    }
    
    double a2d_get(Array2D *a, int y, int x) {
    	assert(a != NULL);
    	assert(x < a->w);
    	assert(y < a->h);
    	
    	return *(a->data + x + y*a->w);
    }
    
    void a2d_set(Array2D *a, int y, int x, double d) {
    	assert(a != NULL);
    	assert(x < a->w);
    	assert(y < a->h);
    	
    	*(a->data + x + y*a->w) = d;
    }
    
    Has a truck load of asserts sprinkled throughout the code. Doesn't affect runtime speed if you define NDEBUG. Not the most beautiful code in the world, but it works, and it's fast, and it's portable. Daddy like :).
     
  12. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    For all my attempts at optimization in C, I've found that Java code runs just as fast. And it's a lot easier to work with, since arrays hold their own length, and bounds are checked. Given that Objective-C isn't faster than C, it makes me wonder if I should even bother with it.

    Looks like I'll be sticking with Java for the rest of my code.
     
  13. cfleck

    cfleck tired

    Joined:
    Nov 9, 2002
    Messages:
    825
    Likes Received:
    2
    Trophy Points:
    0
    Location:
    Indianapolis
    I'm curious. How big are the arrays you are playing with?
     
  14. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    They range from 10,000 elements (in cache) to 10,000,000 elements (stresses memory subsystem). These are doubles.
     
  15. Krevinek

    Krevinek Evil PPC Tweaker

    Joined:
    Oct 11, 2001
    Messages:
    645
    Likes Received:
    1
    Trophy Points:
    0
    Well, you could always code a class or set of functions to do the offsets and the like for you. This way you can get contigous space (although the size of your elements is large enough that keeping them in cache is gonna be tough), and ease of use outside of the class. That is the way industry does it.
     
  16. Viro

    Viro Registered

    Joined:
    Nov 6, 2003
    Messages:
    2,497
    Likes Received:
    3
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Oxford, UK
    That's exactly how I've done it. It is 6 posts up :).
     

Share This Page