Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Variable in Parameter List and Output List

Subject: Variable in Parameter List and Output List

From: Eric W

Date: 8 Jul, 2009 16:12:02

Message: 1 of 4

I'm having trouble with a function which is supposed to update one of its argument variables and return it.

Here's the code - I know it's not defined at all, but someone with the answer to this question will be able to answer it without the specifics:

function RateTest(testInfo)
    testInfo = getClips(testInfo);
    testInfo = hashClipMask(testInfo);
    testInfo = generateFrameSeq(testInfo);
    for framePre = testInfo.FrameSeq
        [frameFig,action,framePost] = showFrame(testInfo,framePre);
        switch(action)
            case 'skip'
                continue
            case 'next'
                disp(framePost);
                testInfo = processSelection(testInfo,framePost);
                disp(testInfo.Results);
            otherwise
                return;
        end
    end
    writeResults(testInfo);
end

In all other instances of the code, this works. However, the call to processSelected() shown, does not update the variable testInfo.

In most of the calls where testInfo (a structure) is passed back and forth, I've added a field to it - MATLAB was happy.

In processSelected(), being inside the for loop, I wanted to create the field on the first iteration and update it on each proceeding iteration. I implemented this by checking to see if "Results" (said field) was a fieldname of TestInfo. If it didn't exist, I initialized it. If not, I updated it - MATLAB NOT happy. While inspecting the execution, I noticed it would fail the "fieldname" test and re-initialize "Results" each time.

To get around this -on a hunch- I simply initialized "Results" elsewhere, and MATLAB was again happy. However, this is very strange behavior to me and I'd love to hear an explanation if one exists.

Subject: Variable in Parameter List and Output List

From: Bruno Luong

Date: 8 Jul, 2009 17:40:21

Message: 2 of 4

"Eric W" <gmail@ewilliams2006.com> wrote in message <h32ggi$eqk$1@fred.mathworks.com>...
> I'm having trouble with a function which is supposed to update one of its argument variables and return it.
>
> Here's the code - I know it's not defined at all, but someone with the answer to this question will be able to answer it without the specifics:
>
> function RateTest(testInfo)
> testInfo = getClips(testInfo);
> testInfo = hashClipMask(testInfo);
> testInfo = generateFrameSeq(testInfo);
> for framePre = testInfo.FrameSeq
> [frameFig,action,framePost] = showFrame(testInfo,framePre);
> switch(action)
> case 'skip'
> continue
> case 'next'
> disp(framePost);
> testInfo = processSelection(testInfo,framePost);
> disp(testInfo.Results);
> otherwise
> return;
> end
> end
> writeResults(testInfo);
> end
>
> In all other instances of the code, this works. However, the call to processSelected() shown, does not update the variable testInfo.
>
> In most of the calls where testInfo (a structure) is passed back and forth, I've added a field to it - MATLAB was happy.

Matlab functions don't update any input arguments. You can only update by assign your variables from the left hand side

A = foo(A)
A(:) = foo(B)
A(idx) = foo(C)

function out = foo(in) % you can put "in" on the lhs too
% ...
out = ...
end

Bruno

Subject: Variable in Parameter List and Output List

From: Steven Lord

Date: 8 Jul, 2009 17:44:13

Message: 3 of 4


"Eric W" <gmail@ewilliams2006.com> wrote in message
news:h32ggi$eqk$1@fred.mathworks.com...
> I'm having trouble with a function which is supposed to update one of its
> argument variables and return it.
>
> Here's the code - I know it's not defined at all, but someone with the
> answer to this question will be able to answer it without the specifics:
>
> function RateTest(testInfo)

Note that unless testInfo is a handle object (either a handle to a graphics
object, like a figure or axes, or an instance of a user-defined class that
inherits from the handle class) any changes you make to testInfo inside
RateTest are discarded as soon as RateTest returns, since you haven't
specified testInfo as an output argument.

> testInfo = getClips(testInfo);
> testInfo = hashClipMask(testInfo);
> testInfo = generateFrameSeq(testInfo);
> for framePre = testInfo.FrameSeq
> [frameFig,action,framePost] = showFrame(testInfo,framePre);
> switch(action)
> case 'skip'
> continue
> case 'next'
> disp(framePost);
> testInfo = processSelection(testInfo,framePost);
> disp(testInfo.Results);
> otherwise
> return;
> end
> end
> writeResults(testInfo);
> end
>
> In all other instances of the code, this works. However, the call to
> processSelected() shown, does not update the variable testInfo.
>
> In most of the calls where testInfo (a structure) is passed back and
> forth, I've added a field to it - MATLAB was happy.

Since a struct array is not a handle object, the changes you make inside
RateTest will indeed not be propagated to its caller's workspace.

> In processSelected(), being inside the for loop, I wanted to create the
> field on the first iteration and update it on each proceeding iteration. I
> implemented this by checking to see if "Results" (said field) was a
> fieldname of TestInfo. If it didn't exist, I initialized it. If not, I
> updated it - MATLAB NOT happy. While inspecting the execution, I noticed
> it would fail the "fieldname" test and re-initialize "Results" each time.
>
> To get around this -on a hunch- I simply initialized "Results" elsewhere,
> and MATLAB was again happy. However, this is very strange behavior to me
> and I'd love to hear an explanation if one exists.

There's no real way to determine why you're seeing this behavior without
seeing what processSelection [which I assume is the function you're calling
from the code above, not processSelected] is doing. It could be something
like:


function testInfo = processSelection(testInfo, framePost)
newvariable = testInfo;
if ~isfield(newvariable, 'Results')
    newvariable.Results = 5;
end


or something completely different.

--
Steve Lord
slord@mathworks.com

Subject: Variable in Parameter List and Output List

From: Eric W

Date: 8 Jul, 2009 17:52:01

Message: 4 of 4

"Steven Lord" <slord@mathworks.com> wrote in message <h32lrp$k9h$1@fred.mathworks.com>...
>
> "Eric W" <gmail@ewilliams2006.com> wrote in message
> news:h32ggi$eqk$1@fred.mathworks.com...
> > I'm having trouble with a function which is supposed to update one of its
> > argument variables and return it.
> >
> > Here's the code - I know it's not defined at all, but someone with the
> > answer to this question will be able to answer it without the specifics:
> >
> > function RateTest(testInfo)
>
> Note that unless testInfo is a handle object (either a handle to a graphics
> object, like a figure or axes, or an instance of a user-defined class that
> inherits from the handle class) any changes you make to testInfo inside
> RateTest are discarded as soon as RateTest returns, since you haven't
> specified testInfo as an output argument.
>
> > testInfo = getClips(testInfo);
> > testInfo = hashClipMask(testInfo);
> > testInfo = generateFrameSeq(testInfo);
> > for framePre = testInfo.FrameSeq
> > [frameFig,action,framePost] = showFrame(testInfo,framePre);
> > switch(action)
> > case 'skip'
> > continue
> > case 'next'
> > disp(framePost);
> > testInfo = processSelection(testInfo,framePost);
> > disp(testInfo.Results);
> > otherwise
> > return;
> > end
> > end
> > writeResults(testInfo);
> > end
> >
> > In all other instances of the code, this works. However, the call to
> > processSelected() shown, does not update the variable testInfo.
> >
> > In most of the calls where testInfo (a structure) is passed back and
> > forth, I've added a field to it - MATLAB was happy.
>
> Since a struct array is not a handle object, the changes you make inside
> RateTest will indeed not be propagated to its caller's workspace.
>
> > In processSelected(), being inside the for loop, I wanted to create the
> > field on the first iteration and update it on each proceeding iteration. I
> > implemented this by checking to see if "Results" (said field) was a
> > fieldname of TestInfo. If it didn't exist, I initialized it. If not, I
> > updated it - MATLAB NOT happy. While inspecting the execution, I noticed
> > it would fail the "fieldname" test and re-initialize "Results" each time.
> >
> > To get around this -on a hunch- I simply initialized "Results" elsewhere,
> > and MATLAB was again happy. However, this is very strange behavior to me
> > and I'd love to hear an explanation if one exists.
>
> There's no real way to determine why you're seeing this behavior without
> seeing what processSelection [which I assume is the function you're calling
> from the code above, not processSelected] is doing. It could be something
> like:
>
>
> function testInfo = processSelection(testInfo, framePost)
> newvariable = testInfo;
> if ~isfield(newvariable, 'Results')
> newvariable.Results = 5;
> end
>
>
> or something completely different.
>
> --
> Steve Lord
> slord@mathworks.com
>

In every call, I specifically DO pass the argument back as an output. Inside for loops, however, new fields are not added to structures. I have run into this same exact issue again, with another field. Here is the contents of processSelection

function testInfo = processSelection(testInfo,frameInfo)
    
    expected = frameInfo.CorrectType;
    response = frameInfo.Response;
    numPlays = frameInfo.TotalPlays;
    correct = frameInfo.isCorrect;

    resultQuestionStr = [frameInfo.Color ' ' frameInfo.Shape];
    frameNum = num2str(frameInfo.FrameNum);
    resultLine = [cellstr(frameNum),cellstr(resultQuestionStr),...
        cellstr(response),cellstr(expected),cellstr(correct),cellstr(num2str(numPlays))];
   

    sectionName = [frameInfo.Speed '_' frameInfo.SpeakerType];
    sectionIndex = size(testInfo.Results.(sectionName),1) + 1;
    testInfo.Results.(sectionName)(sectionIndex,1:length(resultLine)) = resultLine(:) ;
    
    index = size(testInfo.Results.Total,1) + 1;
    testInfo.Results.Total(index,1:length(resultLine)) = resultLine(:);
end

Previously, there was the:

> if ~isfield(testInfo, 'Results')
> testInfo.Results = 5;
> end

You mentioned. However, this ALWAYS occured, no matter if it was the first iteration or not.

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us