# Returning a (multi-dimensional) Variant Array as a function result

I have a function that processes and returns a variant array. so far the array is one dimensional (I'll call it an array with one column), and everything works fine.  bwLPF function always takes in a one-column variant array, and will return a one column variant array.  See working code below for one-column arrays.  (For one column array: TimeHistory[0] := 0, TimeHistory[1] := 0.25, and so on..)

I want to expand this to array of variable number of columns.  Basically, I want the function to process each column by recursion.

I tried "NewButterworthLPF" (see below) without success.   Input for the new function was created as

V := VarArrayCreate([0, 2], varVariant);
V[0] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);
V[1] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);
V[2] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);
V[0] :=  History1;
V[1] :=  History2;
V[2] :=  History3;
V := NewButterworthLPF(V, fs, fc, fOrder);

so, TimeHistory will look like:
TimeHistory[0][0] := 0, TimeHistory[0][1] := 0.21 and so on for column 0
TimeHistory[1][0] := 0, TimeHistory[1][1] := 0.05 and so on for column 1, etc

What am I missing ?  (also would it be better to use a multi-dimensional Variant array, instead of using a 1-D varVariant array in which each column is an array of varDouble  ?).  A working sample that uses recursion to solve the problem will get the points.

Thanks.

``````function ButterworthLPF(TimeHistory:OleVariant; SamplingFrequency, CutOffFrequency:real; FilterOrder:byte=8):OleVariant;
//This works for 1-column input

var fs, fc, odr   : OleVariant;

begin;
fs  := SamplingFrequency;
fc  := CutOffFrequency;
odr := FilterOrder div 2;
result := bwLPF(TimeHistory, fs, fc, odr);
end;

function NewButterworthLPF(TimeHistory:OleVariant; SamplingFrequency, CutOffFrequency:real; FilterOrder:byte=8):OleVariant;
//This does NOT work for 3-column input

var fs, fc, odr   : OleVariant;
i, j : integer;
vt : TVarType;

begin;
vt := VarType(TimeHistory);
if (vt and varVariant = varVariant) then
for i := 1 to VarArrayHighBound(TimeHistory, 1) do
result[i] := NewButterworthLPF(TimeHistory[i], SamplingFrequency, CutOffFrequency, FilterOrder)
else

fs  := SamplingFrequency;
fc  := CutOffFrequency;
odr := FilterOrder div 2;
result := bwLPF(TimeHistory, fs, fc, odr);
end;
``````
LVL 7
Asked:
###### Who is Participating?

Author Commented:
yes, but you don't need this check after all.   The only thing needed to differentiate Variant array of double from a Variant array of Variant array of double is my original check:   if (vt and varVariant = varVariant)  then ....

I made the code to work by adding  Result := VarArrayCreate([0, VarArrayHighBound(TimeHistory, 1)], varVariant); before starting the recursion.  See below for my final solution.  Let me know if you see any errors with this.
``````function NewButterworthLPF(TimeHistory : Variant; SamplingFrequency, CutOffFrequency:real; FilterOrder:byte=8) : Variant;
//This does seem to work for both single column, and multi column inputs.

var fs, fc, odr   : OleVariant;
i, j : integer;
vt : TVarType;

begin;
vt := VarType(TimeHistory);
if (vt and varVariant = varVariant) then
begin;
Result := VarArrayCreate([0, VarArrayHighBound(TimeHistory, 1)], varVariant);
for i := 1 to VarArrayHighBound(TimeHistory, 1) do
result[i] := NewButterworthLPF(TimeHistory[i], SamplingFrequency, CutOffFrequency, FilterOrder);
end
else
begin;
fs  := SamplingFrequency;
fc  := CutOffFrequency;
odr := FilterOrder div 2;
result := bwLPF(TimeHistory, fs, fc, odr);
end;
end;
``````
0

Commented:
Hi,

Try the following.
``````function NewButterworthLPF(TimeHistory : Variant; SamplingFrequency, CutOffFrequency:real; FilterOrder:byte=8) : Variant;
var
fs, fc, odr   : OleVariant;
i, j : integer;
vt : TVarType;
begin
vt := VarType(TimeHistory);
if (vt and varVariant = varVariant) and (TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and VarVariant = varVariant) then
begin
Result := VarArrayCreate([0, VarArrayHighBound(TimeHistory, 1)], varVariant);
for i := 0 to VarArrayHighBound(TimeHistory, 1) do
begin
Result[i] := NewButterworthLPF(TimeHistory[i], SamplingFrequency, CutOffFrequency, FilterOrder)
end;
end
else
begin
fs  := SamplingFrequency;
fc  := CutOffFrequency;
odr := FilterOrder div 2;
result := bwLPF(TimeHistory, fs, fc, odr);
end;
end;
``````
0

Author Commented:
I'll try your code when I get a chance, but you should give comments on why you suggest, what you suggest as well please.
0

Author Commented:
Nope, doesn't work.

I don't understand why you have
(TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and VarVariant = varVariant) ??

My FHistoryOriginal is a Variant array of type varDouble.
0

Commented:
>>My FHistoryOriginal is a Variant array of type varDouble
I guess you are using the array you posted earlier. i.e.
V := VarArrayCreate([0, 2], varVariant);
V[0] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);
V[1] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);
V[2] := VarArrayCreate([0, VarArrayHighBound(FHistoryOriginal, 1)], varDouble);

Here, V[0] is an array of variant. NO matter what data type you specify. The data type of its individual element would be Double. i.e. V[0][0]. And thus V is a variant array of variant array.

>>(TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and VarVariant = varVariant) ??

In your original function (which doesn't work for multi column) you have
vt := VarType(TimeHistory);
if (vt and varVariant = varVariant)  ...

So if you pass V (variant array of variant array) to NewButterworthLPF function, in the first pass, "if (vt and varVariant = varVariant)" will return true and will call itself with its V[i] element. Now if I understand correctly, V[i] should be executed on same code which you use in your ButterworthLPF function. i.e.
fs  := SamplingFrequency;
fc  := CutOffFrequency;
...

But  in your original code "if (vt and varVariant = varVariant)" will again return true for V[i] and will call itself again. Which I thought INCORRECT.

Based on that understanding, I checked V[i][j] element of V using
(TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and VarVariant = varVariant)

Which will branch the V[i] element to the else part of your function.

If that's what you want; my function should work for variant array as well as variant array of variant array. If not, tell me how you use the function with some DUMMY data which I can test.

Atul
0

Author Commented:
Atul,

I was using the array I posted earlier.  I understand that V is a variant array of variant array (of Double).

I want to be able to pass either of the following:
Case 1 (Recursion) : V -> Variant array of variant array
Case 2: (No recursion) V -> Variant Array.

I will make a short sample and post it to show you what I am after.  Thanks.
0

Author Commented:
Atul,

While exploring you code, found the following.

Say
U := VarArrayCreate([0, 2047], varDouble);
vt := VarType(U);     //vt is not varVariant, instead it is varDouble

V := VarArrayCreate([0, 4], varVariant);
for i := 0 to 4 do
begin;
U := VarArrayCreate([0, 2047], varDouble);
for j := 0 to 2047 do U[j] := random;
V[i] := U;
end;

vt := VarType(V);        //vt is varVariant
vt := VarType(V[1]);     //vt is not varVariant, it is varDouble

This suggests that your suggestion regarding varType is not correct.  Can you confirm.
0

Author Commented:
The check that is needed is the following:

vt1 := VarType(TimeHistory);
vt2 := VarType(TimeHistory[VarArrayLowBound(TimeHistory, 1)]);

if (vt2 and varArray = varArray) then ...
0

Commented:
Correct;
vt2 := VarType(TimeHistory[VarArrayLowBound(TimeHistory, 1)]);
if (vt2 and varArray = varArray)

IS SAME AS

IF (TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and VarVariant = varVariant)

0

Commented:
My misatake; it should be
IF (TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and varArray= varArray)
0

Commented:
>>yes, but you don't need this check after all.
It depends on the variant array you are passing. e.g. try with following array

var
V, V1 : Variant;
begin
V := VarArrayCreate([0, 2], varVariant);
V1 := VarArrayCreate([0, 1], varDouble);
V[0] := VarArrayOf(V1);
V[1] := VarArrayOf(V1);
V[2] := VarArrayOf(V1);
NewButterworthLPF(V, 0, 0); // call to your function
end;

Atul.
0

Commented:
It works well with the code I posted first.

...
if (vt and varVariant = varVariant) and (TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and varVariant = varVariant) then
...
0

Author Commented:
I haven't had a chance to try with an array as you have defined above. But, my question had the arrays defined in a specific way, and your solution doesn't work with that.

But, I managed to tweak my code (adding a line to create result as a VarArray) after seeing your solution.  Thanks.
0

Commented:
>>The solution I posted in the question required the addition one just one line of >>code to make it work.  (I figured it out myself after discussions).

My first post has the line (line#10) which makes this work.

>>The answer posted posted might be correct for a different question, but it's not >>the answer for the posted question.

There are numerous ways to solve a problem. It doesn't matter which one u like or dislike.

If, the posted comment doesn't lead to solve the problem. I would rather suggest to delete this question.
0

Author Commented:
Atul,

>> My first post has the line (line#10) which makes this work.

Even though you had that line, your solution was wrong, and did not work.  I accepted your suggestion as an "Assisted Solution" because I picked up your line 10.   I cannot accept your solution as a full solution, because it did not work with my array.

Accepting your solution as an "Assisted Solution" was fair, I thought. Don't you think so ?

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

## Already a member? Login.

All Courses

From novice to tech pro — start learning today.