Menu

in-struct indexing issues in sub-function

Help
2016-11-01
2016-11-08
  • Jaime F. Fisac

    Jaime F. Fisac - 2016-11-01

    Hi Matt,

    ADiGator is awesome, thanks for putting it out there, I can't tell you how many painful hours of coding it's saved me!

    I'm noticing a funny issue when trying to index array variables in structs within a sub-function. In particular, I'm trying to have a sub-function inside the "continuous function" in GPOPS II, passing the whole "input" struct as an argument. I'm running adigatorGenFiles4gpops2 to debug the derivative generation process.

    When I try to index or otherwise access the dimensions of any variable inside the struct, I get an ADiGator error. This happens only if I do it from the sub-function, but not from the main function. For example, if my function contains the code

    t = input.phase.time;
    zero_t = zeros(size(t));
    

    that works just fine with ADiGator. But suppose instead I do

    t = input.phase.time;
    zero_t = allZeros(input);
    
    %%%%%
    
    function z = allZeros(input)
        t = input.phase.time;
        z = zeros(size(t));
    end
    

    then this produces an error. In this case, it's

    Error using zeros
    NaN and Inf not allowed.
    

    Similar attempts to access the dimensions of t lead to errors. For example, if I include the line

    t0 = input.phase.time(1);
    

    I get the error

    Error using cada/subsref (line 86)
    Invalid vectorized subsref
    
    Error in cadastruct/subsref (line 46)
        y = subsref(y,s(dotcount+1:end));
    

    It seems as if ADiGator is somehow losing track of the dimensions of the array when it gets passed to the sub-function inside the struct. Any thoughts on why this might be happening and if there may be a workaround for it?

    Thanks a lot!
    Jaime

     
  • Matthew J. Weinstein

    Jaime,

    I am glad you are finding it useful. For the first issue, I am not exactly sure what is going on there. How it is supposed to work is that within the subfunction, "t" will be overloaded and call overloaded @cada/size. @cada/size will behave in one of two ways depending upon where it is being called from. It determines the "calling file" via:

    Dbstuff = dbstack; CallingFile = Dbstuff(2).file;
    

    if this begins with "adigatortempfunc", it returns an overloaded object for the size. Otherwise, it returns the size of the overloaded object, in the case of the vectorized (continuous) functions, the vectorized dimension is stored in cada objects as an "inf".

    So, I am guessing there is an issue with where the above "CallingFile" variable is pointing to. I tried to reproduce the error with the following function:

    function out = myfun(in)
    
    out = allZeros(in);
    
    out = out + in.phase.x(:,1) + in.phase.x(:,2);
    
    end
    
    function z = allZeros(in)
    
    t = in.phase.t;
    z = zeros(size(t));
    
    end
    

    and driving code:

    dinfo.vodname = 'x';
    dinfo.vodsize = [inf 3];
    dinfo.nzlocs  = [1 1];
    in.phase.t = adigatorCreateDerivInput([inf 1],dinfo);
    dinfo.nzlocs  = [1 2;2 3];
    in.phase.x = adigatorCreateDerivInput([inf 2],dinfo);
    
    adigator('myfun',{in},'myder',adigatorOptions('overwrite',1));
    

    but was unable to. What version of Matlab are you using and on what OS? I am guessing that the dbstack function is behaving differently for some reason.

    As a workaround, that mechanism only fires when size(x) is used (this is because the Matlab workspace is constantly calling size(x) on all variables in the workspace). If you use size(x,1) or size(x,2), then this mechanism will be by-passed.

    For the second comment, when in the vectorized mode it simply won't allow you to reference off a single element from the vectorized dimension as this creates a non-vectorized variable which is dependent upon a vectorized variable.

    Matt

     
  • Jaime F. Fisac

    Jaime F. Fisac - 2016-11-08

    Hi Matt,

    Thanks a lot for your quick reply. The size(x,1) workaround certainly works (I'm using MATLAB 2016a on macOS Sierra).

    Funnily enough, your code indeed does not reproduce the error I get in my original function (which does have a few more lines), so it seems as though the error might be triggered by something else I'm doing upstream of the sub-function call. I'll investigate this a bit further and let you know if I figure out what's going on in case it's relevant.

    Thanks again!

    Jaime

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.