views:

195

answers:

4

I am writing some matrix routines in Delphi and this problem came up. I have defined a real matrix thus:-

RealArrayNPbyNP = Array[1..200,1..200] of Extended;

I have populated this array with a 5 x 6 matrix.

How do I query the array to get the number of rows (which in this case will be 5) and the number of cols (which in this case will be 6) in delphi code.

A: 

If you can guarantee that the matrix is initially populated with known values, e.g., 0 or some invalid value, then you can do what amounts to strlen() and simply count the number of elements in the first row and column that are present before the flag value. This tends to be inefficient, however. Why can't you just pass the current size around as you need it? Or better yet, encapsulate your matrix functionality in a proper object.

Jon Purdy
Thanks.You understand my problem.That is the solution I am leaning to but since a real number can have any value under the sun, what is that value that I can initialize the matrix/array with? can I put NULL as a real number?
earlcenac
You could set it to `Infinity` or `NaN`, whichever you prefer, and use `IsInfinite` or `IsNaN` to test it. I still recommend preserving size information somewhere.
Jon Purdy
I have used the NaN value to initialize the array with and I have written a procedure to get the rows and columns that is filled with my data using the Isnan function to query the data.
earlcenac
Glad that this solution works for you. Could you please accept my answer?
Jon Purdy
How do I accept your answer?
earlcenac
Click the big ol' checkmark on the left.
Jon Purdy
+3  A: 

You declared the matrix as 200 x 200. No matter how much of it you use, the matrix is always 200 x 200. All fields outside of your 5 x 6 range contain at least some data, be it useful or not.

Perhaps you should consider using dynamic arrays:

var
  arr: array of array of Extended

With this you can use Setlength to fit the array dimensions to your needs. To get a 5x6 matrix you can use this code (thanks to Rob for the hint):

SetLength(arr, 5, 6);

As you can see, the actual dimension can be queried with the Length function. Length(arr) gets the first dimension while Length(arr[I) will give the second dimension.

With this construct each "row" of the matrix can have an independent number of "columns".

Uwe Raabe
Note that the dynamic arrays are always zero-based, i.e. the resulting array has [0..4, 0..5] dimensions
Serg
Thanks. But that is not my problem. I want to find the number of rows and columns actually populated with MY DATA, as I explained in my question
earlcenac
What do you mean by "populated"? The array is already populated when you declare it - at least with random data.
Uwe Raabe
Or even `SetLength(arr, 5, 6)`.
Rob Kennedy
how can you populate an array of Extended with "MY DATA" ? Please read and answer Runner's comment to your question.
PA
@PA: could it be that your comment belongs to the original question?
Uwe Raabe
I mean data that I input into the array myself (My DATA). The array may be 200 x 200 elements but I may have populated(inputted) it with a 5 x 5 array.
earlcenac
+2  A: 

If you don't want a dynamic array and have no additional information as to which values constitute valid ones (i.e., if you can't search for them/count them), you'll essentially have to have additional information. In other words, you'd need two more variables, NRows and NColumns which you set when you populate the array.

PhiS
I can go this route, but I choose not to. I rather initialize the array with NaN values as suggested by Jon Purdy below. It will help teach me the "initialize before you use" best practice for using variables.
earlcenac
@earlcenac: That's perfectly OK, of course.
PhiS
A: 

If I understand your problem correctly, what your trying to do is to have a preallocated array, which you are only filling partially and your wanting to determine how much is filled.

I would create a class which contains all of the logic for dealing with this "array" and write a property setter for the array which contained the following logic:

Procedure SetArrayValue(X,Y:Extended);
begin
  fInternalArray[x,y] := Extended;
  fInternalArrayMaxX := Max(fInternalArrayMaxX,X);
  fInternalArrayMaxY := Max(fInternalArrayMaxY,Y);
end;

and an array initialization/clear function which looked like the following:

Procedure ClearArray;
begin
  FillMemory(@fInternalArray,SizeOf(fInternalArray),0);
  fInternalArrayMaxX := 0;
  fInternalArrayMaxY := 0;
end;

You can also extend the determination of if an array element has a value by adding another array which matches the bounds of boolean and modifying it appropriately.

skamradt
Tkanks. I cannot use 0 to initialize the array because my arrays will have a ot of zero values. I have used the Delphi's NaN number instead.This works fine.
earlcenac
I meant to say above that "I will be filling my arrays with a lot of zero values".
earlcenac