?
Solved

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

Posted on 2008-10-06
15
Medium Priority
?
2,297 Views
Last Modified: 2013-11-13
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;

Open in new window

0
Comment
Question by:ahalya
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 7
15 Comments
 
LVL 10

Assisted Solution

by:atul_parmar
atul_parmar earned 400 total points
ID: 22656957
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;

Open in new window

0
 
LVL 7

Author Comment

by:ahalya
ID: 22658571
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
 
LVL 7

Author Comment

by:ahalya
ID: 22675473
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
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

 
LVL 10

Expert Comment

by:atul_parmar
ID: 22684613
>>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
 
LVL 7

Author Comment

by:ahalya
ID: 22686309
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
 
LVL 7

Author Comment

by:ahalya
ID: 22687005
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
 
LVL 7

Author Comment

by:ahalya
ID: 22687077
The check that is needed is the following:

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

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

Expert Comment

by:atul_parmar
ID: 22687118
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
 
LVL 10

Expert Comment

by:atul_parmar
ID: 22687188
My misatake; it should be
IF (TVarData(TimeHistory[VarArrayLowBound(TimeHistory, 1)]).VType and varArray= varArray)
0
 
LVL 7

Accepted Solution

by:
ahalya earned 0 total points
ID: 22687438
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;

Open in new window

0
 
LVL 10

Expert Comment

by:atul_parmar
ID: 22700351
>>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
 
LVL 10

Expert Comment

by:atul_parmar
ID: 22700361
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
 
LVL 7

Author Comment

by:ahalya
ID: 22739985
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
 
LVL 10

Expert Comment

by:atul_parmar
ID: 22740357
>>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
 
LVL 7

Author Comment

by:ahalya
ID: 22741277
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

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question