Simple: Just do not assume the vector is consecutive in memory.
Originally Posted by Darkmentor
Instead of a simple linear array, specify the data as a pointer, number of data items between consecutive elements (stride), and vector size (element count):
The strides you can trivially compute:
double my_function(double *const vector, const long stride, const long size)
/* Element i (0 <= i < size), is (vector[i * stride]). */
- (long)(&Solution - &Solution) for a row vector -- I do believe this is defined to be 1 in C
- (long)(&Solution - &Solution) for a column vector
- (long)(&Solution - &Solution) for a plane vector
Note that the stride is not in units of bytes or chars, but the data units, here doubles, so the data types matter. If you use the actual data array to compute the (three) strides, it will be correct every time. You could use for example
If you supply the pointer to the final element, and negate the stride, you can reverse the vector component order, too. It is sometimes very useful.
#define PLANES 3
#define ROWS 20
#define COLUMNS 20
const long Solution_row = 1L;
const long Solution_column = &Solution - &Solution;
const long Solution_plane = &Solution - &Solution;
/* Third column vector (column 2): */
result = my_function(&Solution, Solution_column, ROWS);
There are also two-dimensional and higher-dimensional equivalents, of course: just specify the size and stride for each dimension separately. In 2D, for example:
but I personally prefer to define structures (with the size and stride fields, and a pointer to the data origin). Let me know if you want examples.
double my_function(double *const plane, const long rowstride, const long colstride, const long rows, const long cols)
/* Element (r,c), (0 <= r < rows, 0 <= c < cols) is
* plane[r * rowstride + c * colstride]