Announcement

Collapse
No announcement yet.

Accessing arrays returned by efsExternal

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Accessing arrays returned by efsExternal

    Hello Alex/Jason/Steve:

    I have an efs returns 2 arrays.
    In the calling efs I have:

    var myVar = efsExternal("xyz.efs", param1);

    In xyz.efs :

    var array1 = new Array ();
    var array2 = new Array ();

    return new Array (array1, array2);

    Back in calling efs:

    var a1 = new Array();
    var a2 = new Array();

    a1 = getSeries(myVar, 0);
    a2 = getSeries(myVar, 1);

    but a1, a2 are nulls even though if I run xys.efs as an independent efs, array1 and array2 are filled with correct data.

    Please advise. Thank you.

    ziggy

  • #2
    Hello ziggy,

    EFS does not support multi-dimensional return arrays from main(), which in turn makes efsExternal() limited to single dimensional return arrays from the external EFS. You will have to split your xyz.efs into two separate formulas where each returns a one dimensional array and add a second efsExternal() series in your calling EFS.
    Jason K.
    Project Manager
    eSignal - an Interactive Data company

    EFS KnowledgeBase
    JavaScript for EFS Video Series
    EFS Beginner Tutorial Series
    EFS Glossary
    Custom EFS Development Policy

    New User Orientation

    Comment


    • #3
      Thanks for the clarification, Jason.

      Is there any mechnism what would handle 2-D arrays? such as efsInternal? efsLibrary?

      ziggy

      Comment


      • #4
        Hello ziggy,

        Same problem exists with efsInternal(). It is not designed to accept a multi-dimensional array. With a function library, or any regular user-defined function, you can return a multi-dimensional array. However, as soon as you try to pass that return into the form of a series object you will run into the limitation.

        What might work for you is to use a function library to return the multi-dimensional array like below.

        test.efsLib
        PHP Code:
        var array1 = new Array (123);
        var 
        array2 = new Array (102030);

        function 
        calc() {
            return new Array(
        array1array2);

        Then in the calling efs you could split the first dimension of this array back into single dimensional arrays and then convert those into series objects through two efsInternal() calls. The example below is a crude one, but it works.

        PHP Code:
        var myLib addLibrary("test.efsLib");

        function 
        main() {
            var 
        myVar1 efsInternal("xyz"0);
            var 
        myVar2 efsInternal("xyz"1);
            
            var 
        a1_0 getSeries(myVar10);
            var 
        a1_1 getSeries(myVar11);
            var 
        a1_2 getSeries(myVar12);
            var 
        a2_0 getSeries(myVar20);
            var 
        a2_1 getSeries(myVar21);
            var 
        a2_2 getSeries(myVar22);
            
            return new Array(
        a1_0a1_1a1_2a2_0a2_1a2_2);
        }

        function 
        xyz(n) {
            var 
        myVar myLib.calc();
            
        //debugPrintln(myVar.length);

            
        return myVar[n];


        If the elements in array1 and array2 need to be in the form of series objects, then this function library scenario will not work. You'll have to go with the suggestion of splitting xyz.efs into two formulas. Or you could add an additional parameter to xyz.efs to tell it to return only array1 or array2 so that you are always dealing with a one dimensional return array from xyz.efs.
        Jason K.
        Project Manager
        eSignal - an Interactive Data company

        EFS KnowledgeBase
        JavaScript for EFS Video Series
        EFS Beginner Tutorial Series
        EFS Glossary
        Custom EFS Development Policy

        New User Orientation

        Comment


        • #5
          Thanks Jason for these finer points.

          1) calling the efs external twice with different parameters so that it knows which array to return sounds like it will work...but won't that create double the overhead? I mean each time you call an efs external, that efs gets loaded...once it returns, does it get "thrown out" of dynamic memory? and it gets loaded again the next time it is called? As for efs internal, that gets loaded once with the calling efs and stays in memory as long as the calling efs is live? and efsLibrary calls would behave the same as efsExternal? Am I correct in my understanding?

          2) Just to be sure, in efsExternal:

          var a1=new Array (1,2,3);
          ...
          return new Array (a1);

          and then in calling efs:

          var myVar = efsExternal("xyz.efs", param1);
          var v1 = getSeries(myVar, 0).getValue(0);
          var v2 = getSeries(myVar, 0).getValue(1);
          var v3 = getSeries(myVar, 0).getValue(2);

          So v1 = 1?, v2 =2, v3 = 3?

          ziggy


          ziggy

          Comment


          • #6
            Hello ziggy,

            1) Once you create the series object from an efsExternal() call on the first iteration, that object remains in memory just like it does for efsInternal(). When you make two separate series in your calling efs by calling the same external efs, you will have two series objects in memory. They do not get destroyed and recreated on each iteration of main() in the calling efs. If you want to improve the efficiency of the code a bit, you can make the series object variables global and then initialize them in a bInit or null check routine like below.

            PHP Code:
            var myVar null;

            function 
            main() {
                if (
            myVar == nullmyVar efsExternal("xyz.efs"param1);

                var 
            v1 getSeries(myVar0);
                var 
            v2 getSeries(myVar1);
                var 
            v3 getSeries(myVar2);

                return new Array(
            v1v2v3);

            2) I think your understanding here is correct, but your code example was slightly incorrect. The code example above would be the correct way to reference the elements of the return array where v1 = 1, v2 = 2 and v3 = 3. The code example in my previous post is also a good way to verify this process if you run that code. Below is the calling efs code from my previous post with the bInit routine added.

            PHP Code:
            var myLib addLibrary("test.efsLib");
            var 
            myVar1 null;
            var 
            myVar2 null;
            var 
            bInit false;

            function 
            main() {
                if (
            bInit == false) {
                    
            myVar1 efsInternal("xyz"0);
                    
            myVar2 efsInternal("xyz"1);
                    
            bInit true;
                }

                var 
            a1_0 getSeries(myVar10);
                var 
            a1_1 getSeries(myVar11);
                var 
            a1_2 getSeries(myVar12);
                var 
            a2_0 getSeries(myVar20);
                var 
            a2_1 getSeries(myVar21);
                var 
            a2_2 getSeries(myVar22);
                
                return new Array(
            a1_0a1_1a1_2a2_0a2_1a2_2);
            }

            var 
            myVar null;

            function 
            xyz(n) {
                if (
            myVar == nullmyVar myLib.calc();
                
            //debugPrintln(myVar[1]);
                
            return myVar[n];

            Jason K.
            Project Manager
            eSignal - an Interactive Data company

            EFS KnowledgeBase
            JavaScript for EFS Video Series
            EFS Beginner Tutorial Series
            EFS Glossary
            Custom EFS Development Policy

            New User Orientation

            Comment


            • #7
              Thanks Jason for the further clarification.

              I am doing exactly as your sample code is shown whereby I declare a globa var pointing to efsExternal which got assigned within bInit check. I then try to access the elements of returned array as you do in the sample yet I got nulls....I did a debugprint in the efsExternal which showed valid data.

              I like to stress that an array object is the single item being returned by efsExternal in such a statement:

              return new Array (retArray);

              where retArray = (1, 2, 3 .... n)

              is that the right way to do it?

              ziggy

              Comment


              • #8
                Hello ziggy,

                If retArray is already an array you just need to return that by its self. Give this a try.

                return retArray;

                The way you are currently are returning the array through new Array(retArray), it is still a two dimensional array where the first dimension is a size of 1, which contains your retArray.
                Jason K.
                Project Manager
                eSignal - an Interactive Data company

                EFS KnowledgeBase
                JavaScript for EFS Video Series
                EFS Beginner Tutorial Series
                EFS Glossary
                Custom EFS Development Policy

                New User Orientation

                Comment


                • #9
                  Hi JasonK and/or anyone who knows,

                  In your sample below you create two global variables as arrays for the test.efsLib as follows:
                  PHP Code:
                  var array1 = new Array (123);
                  var 
                  array2 = new Array (102030);

                  function 
                  calc() {
                      return new Array(
                  array1array2);

                  Then you call the test.efsLib via the efsInternal function:

                  PHP Code:
                  function xyz(n) {
                      var 
                  myVar myLib.calc();
                      
                  //debugPrintln(myVar.length);

                      
                  return myVar[n];

                  Then from main() you retrieve the two series created in function xyz(n) using:

                  PHP Code:
                      if (bInit == false) {
                          
                  myVar1 efsInternal("xyz"0);
                          
                  myVar2 efsInternal("xyz"1);
                          
                  bInit true;
                      } 
                  I understand that the 0 and 1 in myVar# = efsInternal("xyz",#) refer to each of the series returned by efsInternal.

                  As I understand it this is only possible because "function calc()" in test.efsLib doesn't require parameters passed to it since the two arrays are just globals for that efsLib:
                  PHP Code:
                  var array1 = new Array (123);
                  var 
                  array2 = new Array (102030); 
                  Question: Is there a way to do the same thing but still pass an array such as "hl2()" from the calling efs through the efsInternal to the efsLib and still be able to get the two arrays returned by test.efsLib?

                  I can't get it to work but something like:

                  from main()
                  PHP Code:
                  var mVar1 efsInternal("TestDual"gammavhl20);
                  var 
                  mVar2 efsInternal("TestDual"gammavhl21); 
                  from efsInternal "TestDual":
                  PHP Code:
                  function TestDual(vgamma,zhl2,n){

                      
                  Fixx LAGUER.fFilt(vgammazhl2);
                     return 
                  Fixx[n];

                  to LAGUER1.efsLib:
                  PHP Code:
                  function fFilt(gamma,xhl2) {
                  ...
                      return new Array(
                  FiltFIR); 
                  finally plot the returned arrays in main():
                  PHP Code:
                      return new Array(getSeries(mVar1), getSeries(mVar2));
                  //or maybe:
                      
                  return new Array(mVar1mVar2);
                  //whichever works 
                  Thanks in advance.

                  wayne
                  Last edited by waynecd; 05-26-2009, 11:00 PM.

                  Comment

                  Working...
                  X