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:
Bug: subfunctions versus overloaded functions

Subject: Bug: subfunctions versus overloaded functions

From: John D'Errico

Date: 14 May, 2009 13:10:04

Message: 1 of 10

I decided to change my nextprime code to allow inputs above 2^32, but still as doubles. This required that I had to change isprime to allow arguments above 2^32. Since isprime is a simple code, trivial even, using trial divisions by the primes below sqrt(N), this should be an easy thing to do. I just added a subfunction called isprime that allowed inputs up to 2^46. The code is identical to the built-in isprime, except for a different range. Since it takes about a second to build the list of primes up to 2^23, this seems about the upper limit of acceptability to me.

The problem is that I've overloaded the isprime function to work for vpi numbers. So nextprime should work transparently for either doubles or vpi numbers. Nextprime is quite simple, it uses a partial Euclidean sieve to only make a few tests using isprime when it MIGHT have found a candidate prime. There is an overloaded version of isprime that works for vpi numbers.

The bug is that when isprime is called as a subfunction, even if the input is a vpi number, MATLAB calls the supplied subfunction instead, not the overloaded version for vpi numbers. I could probably get around this bug, but it will take a bit more of a hack than I really wanted to do since now I must add additional tests on the class of a variable. This kludge will slow down the code for smaller inputs when it should be completely unnecessary. Worse, for small numbers, just the test using isa(N,'vpi') to test the class of a variable takes almost as much time as the call to isprime.

I've tried doing a "clear functions" to ensure this was not a cache problem, even restarted MATLAB, but nothing fixes this.

Has anyone else seen this bug? Does this bug still exist in more recent releases? My test was made for R2007b.

Thanks,
John

Subject: subfunctions versus overloaded functions

From: Steven Lord

Date: 14 May, 2009 14:24:58

Message: 2 of 10


"John D'Errico" <woodchips@rochester.rr.com> wrote in message
news:guh57c$9ko$1@fred.mathworks.com...
>I decided to change my nextprime code to allow inputs above 2^32, but still
>as doubles. This required that I had to change isprime to allow arguments
>above 2^32. Since isprime is a simple code, trivial even, using trial
>divisions by the primes below sqrt(N), this should be an easy thing to do.
>I just added a subfunction called isprime that allowed inputs up to 2^46.
>The code is identical to the built-in isprime, except for a different
>range. Since it takes about a second to build the list of primes up to
>2^23, this seems about the upper limit of acceptability to me.
>
> The problem is that I've overloaded the isprime function to work for vpi
> numbers. So nextprime should work transparently for either doubles or vpi
> numbers. Nextprime is quite simple, it uses a partial Euclidean sieve to
> only make a few tests using isprime when it MIGHT have found a candidate
> prime. There is an overloaded version of isprime that works for vpi
> numbers.
>
> The bug is that when isprime is called as a subfunction, even if the input
> is a vpi number, MATLAB calls the supplied subfunction instead, not the
> overloaded version for vpi numbers. I could probably get around this bug,
> but it will take a bit more of a hack than I really wanted to do since now
> I must add additional tests on the class of a variable. This kludge will
> slow down the code for smaller inputs when it should be completely
> unnecessary. Worse, for small numbers, just the test using isa(N,'vpi') to
> test the class of a variable takes almost as much time as the call to
> isprime.
>
> I've tried doing a "clear functions" to ensure this was not a cache
> problem, even restarted MATLAB, but nothing fixes this.
>
> Has anyone else seen this bug? Does this bug still exist in more recent
> releases? My test was made for R2007b.

This isn't a bug, this is the documented behavior.

http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f7-58170.html#bresuvu-3

Subfunctions are second in the precedence order only to variables. I
believe this has been the behavior for quite some time now, at least since
release R13 Service Pack 2 (whose documentation is the oldest present on the
support website):

http://www.mathworks.com/access/helpdesk_r13/help/techdoc/matlab_prog/ch14_o66.html

--
Steve Lord
slord@mathworks.com

Subject: subfunctions versus overloaded functions

From: John D'Errico

Date: 14 May, 2009 14:39:01

Message: 3 of 10

"Steven Lord" <slord@mathworks.com> wrote in message <guh9jn$1bk$1@fred.mathworks.com>...

> This isn't a bug, this is the documented behavior.
>
> http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f7-58170.html#bresuvu-3
>
> Subfunctions are second in the precedence order only to variables. I
> believe this has been the behavior for quite some time now, at least since
> release R13 Service Pack 2 (whose documentation is the oldest present on the
> support website):
>
> http://www.mathworks.com/access/helpdesk_r13/help/techdoc/matlab_prog/ch14_o66.html
>
> --
> Steve Lord
> slord@mathworks.com

Ok, so its not a bug, but a feature, which prevents
overloaded operations from working as they are
designed to work.

Is there a solution besides the kludge of renaming
the subfunction, and then testing the variable type
before each call to determine whether to call the
renamed isprime when I have a double input?

After all, MATLAB is supposed to be smart enough to
know which version of overloaded functions must be
called.

John

Subject: subfunctions versus overloaded functions

From: Charlie D.

Date: 14 May, 2009 16:54:03

Message: 4 of 10

"John D'Errico" <woodchips@rochester.rr.com>
<wants to execute a function shadowed by a subfunction />

I've had this problem in the past, too. I thought a simple solution would be to create a function handle to the specific instance of a shadowed function using relative path notation, i.e., in your case:

fun = @specfun\isprime; %or
fun = str2func('specfun\isprime');

But, it doesn't work.

I'm not sure how to circumvent the precedence of a subfunction. If you are simply trying to access a function that is shadowed by some other function on the path (not a subfunction) a solution is to parse the output of "which -all filename" for the location of the shadowed function, change directory so that the shadowed version has precedence on the path, create the function handle, and change directory back.

Is it a disaster to make the subfunction stand on its own as opposed to being included in the main function? You could then execute whichever version you wished either by manually checking the type yourself (which you indicate you'd like to avoid) or let MATLAB's dispatching rules for overloaded functions do the work.

Hope that's helpful,

CD

Subject: subfunctions versus overloaded functions

From: John D'Errico

Date: 14 May, 2009 17:34:02

Message: 5 of 10

"Charlie D." <ch1ar2le3s.d4av5id6so7n.removeNumbers@a8t9t.net> wrote in message <guhibb$ghs$1@fred.mathworks.com>...
> "John D'Errico" <woodchips@rochester.rr.com>
> <wants to execute a function shadowed by a subfunction />
>
> I've had this problem in the past, too. I thought a simple solution would be to create a function handle to the specific instance of a shadowed function using relative path notation, i.e., in your case:
>
> fun = @specfun\isprime; %or
> fun = str2func('specfun\isprime');
>
> But, it doesn't work.
>
> I'm not sure how to circumvent the precedence of a subfunction. If you are simply trying to access a function that is shadowed by some other function on the path (not a subfunction) a solution is to parse the output of "which -all filename" for the location of the shadowed function, change directory so that the shadowed version has precedence on the path, create the function handle, and change directory back.
>
> Is it a disaster to make the subfunction stand on its own as opposed to being included in the main function? You could then execute whichever version you wished either by manually checking the type yourself (which you indicate you'd like to avoid) or let MATLAB's dispatching rules for overloaded functions do the work.
>
> Hope that's helpful,
>
> CD

Its mainly irritating.

I changed the name of my subfunction to isbigprime,
which does the isprime computation for numbers as
large as 2^46 or so. It still a subfunction, but now has
a non-conflicting name.

Then I set a flag up front that indicated whether I was
looking at doubles or at a vpi number, the alternative
class.

The code then has a switch inside that decides which
function to call. Simple enough in theory, but a kludge
since MATLAB is supposed to be smart enough to know
the difference here.

John

Subject: subfunctions versus overloaded functions

From: Yair Altman

Date: 14 May, 2009 18:58:02

Message: 6 of 10

"John D'Errico" wrote ...
> I changed the name of my subfunction to isbigprime,
> which does the isprime computation for numbers as
> large as 2^46 or so. It still a subfunction, but now has
> a non-conflicting name.
>
> Then I set a flag up front that indicated whether I was
> looking at doubles or at a vpi number, the alternative
> class.
>
> The code then has a switch inside that decides which
> function to call. Simple enough in theory, but a kludge
> since MATLAB is supposed to be smart enough to know
> the difference here.
>
> John

I think that you can keep you original subfunction called isprime, and make no code switch outside it (after all, isprime should hide the implementation details). Then, within your isprime subfunction, use try-catch to process the regular (numeric) way in the try block, incurring negligible performance loss for most (numeric) cases; the VPI cases will be handled in the catch block. Alternately, use a method that only exists for VPIs at the beginning of your try block, thus throwing the normal (numeric) cases to the catch block and continuing with VPIs in the try block. Both of these options look cleaner and possibly better in my eyes.

Another idea is to test if isnumeric(N) - this could be faster than isa(N,'vpi'), although probably slower than try-catch.

To access the built-in isprime you can simply use builtin('isprime',N).

HTH,
Yair

Subject: subfunctions versus overloaded functions

From: Loren Shure

Date: 15 May, 2009 13:31:41

Message: 7 of 10

In article <guhpjq$8gs$1@fred.mathworks.com>, altmanyDEL@gmailDEL.comDEL
says...
> "John D'Errico" wrote ...
> > I changed the name of my subfunction to isbigprime,
> > which does the isprime computation for numbers as
> > large as 2^46 or so. It still a subfunction, but now has
> > a non-conflicting name.
> >
> > Then I set a flag up front that indicated whether I was
> > looking at doubles or at a vpi number, the alternative
> > class.
> >
> > The code then has a switch inside that decides which
> > function to call. Simple enough in theory, but a kludge
> > since MATLAB is supposed to be smart enough to know
> > the difference here.
> >
> > John
>
> I think that you can keep you original subfunction called isprime, and make no code switch outside it (after all, isprime should hide the implementation details). Then, within your isprime subfunction, use try-catch to process the regular (numeric) way in the try block, incurring negligible performance loss for most (numeric) cases; the VPI cases will be handled in the catch block. Alternately, use a method that only exists for VPIs at the beginning of your try block,
thus throwing the normal (numeric) cases to the catch block and continuing with VPIs in the try block. Both of these options look cleaner and possibly better in my eyes.
>
> Another idea is to test if isnumeric(N) - this could be faster than isa(N,'vpi'), although probably slower than try-catch.
>
> To access the built-in isprime you can simply use builtin('isprime',N).

Actually, since isprime is an MATLAB file and not a built in function,
calling builtin in this case won't work.


--
Loren
http://blogs.mathworks.com/loren

Subject: subfunctions versus overloaded functions

From: Mason Freed

Date: 23 Feb, 2011 01:29:04

Message: 8 of 10

Loren Shure <loren@mathworks.com> wrote in message <MPG.247738c679bc0ce9899af@news.mathworks.com>...
>
> Actually, since isprime is an MATLAB file and not a built in function,
> calling builtin in this case won't work.
> --
> Loren
> http://blogs.mathworks.com/loren

I've run into a similar problem, and came across this thread in my search for a solution. My problem is that I have a CLASS that implements a method called unique, to overload the standard method from toolbox\matlab\ops. Inside my function, I just want to handle a couple special cases that I can speed up with knowledge of the workings of my object, but leave the rest of the cases to the standard unique.m. However, as mentioned, I can't call builtin('unique',args) from within my overloaded class method, because it just says "Cannot find builtin function 'unique'". How can I call the "builtin" version of unique here? Help!

Thanks,
Mason

Subject: subfunctions versus overloaded functions

From: Steven_Lord

Date: 23 Feb, 2011 14:46:49

Message: 9 of 10



"Mason Freed" <mfreedREMOVETHIS@mfreedREMOVETHIS.com> wrote in message
news:ik1nt0$5qk$1@fred.mathworks.com...
> Loren Shure <loren@mathworks.com> wrote in message
> <MPG.247738c679bc0ce9899af@news.mathworks.com>...
>>
>> Actually, since isprime is an MATLAB file and not a built in function,
>> calling builtin in this case won't work.
>> --
>> Loren
>> http://blogs.mathworks.com/loren
>
> I've run into a similar problem, and came across this thread in my search
> for a solution. My problem is that I have a CLASS that implements a method
> called unique, to overload the standard method from toolbox\matlab\ops.
> Inside my function, I just want to handle a couple special cases that I
> can speed up with knowledge of the workings of my object, but leave the
> rest of the cases to the standard unique.m. However, as mentioned, I can't
> call builtin('unique',args) from within my overloaded class method,
> because it just says "Cannot find builtin function 'unique'". How can I
> call the "builtin" version of unique here? Help!

What Loren said for ISPRIME is true for UNIQUE as well.

But your version of UNIQUE is a _method_ of your object, not a subfunction,
correct?

If you call UNIQUE and none of the inputs are instances of your class, then
MATLAB will not call the method. So if inside your UNIQUE method you need
to call UNIQUE on a double array, the UNIQUE that ships with MATLAB would be
called instead of your method.

classdef myobj
% Invoke as:
% y = myobj([1:10 1:10]);
% unique(y)
    properties
        data
    end
    methods
        function obj = myobj(x)
            obj.data = x;
        end
        function unique(obj)
            disp('Starting UNIQUE method')
            disp(unique(obj.data));
            disp('Finishing UNIQUE method')
        end
    end
end

When you use the commands given in this class's help text, you should see
the following output:

Starting UNIQUE method
     1 2 3 4 5 6 7 8 9 10

Finishing UNIQUE method

since unique(obj.data) will NOT invoke the method again.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: subfunctions versus overloaded functions

From: Mason Freed

Date: 23 Feb, 2011 16:23:08

Message: 10 of 10

"Steven_Lord" <slord@mathworks.com> wrote in message <ik36kp$h1o$1@fred.mathworks.com>...
>
> What Loren said for ISPRIME is true for UNIQUE as well.
>
> But your version of UNIQUE is a _method_ of your object, not a subfunction,
> correct?
>
> If you call UNIQUE and none of the inputs are instances of your class, then
> MATLAB will not call the method. So if inside your UNIQUE method you need
> to call UNIQUE on a double array, the UNIQUE that ships with MATLAB would be
> called instead of your method.
>
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com

Hi Steven,

Thanks for the quick reply and explanation. Unfortunately, I knew that, but my problem is a bit more subtle. I have overloaded unique to handle some special cases for my class, but I want to use the builtin unique for other cases. In those other cases, I'm still uniquing vectors of my class, not primitive types. My class properly overloads eq, ne, and the comparison operators, so that the builtin unique works properly. It is just slow for some special cases, which I want to handle myself. For example, when the input is the empty vector, the builtin does a whole bunch of extra stuff that is slow.

So... any way to call the builtin unique for objects OF MY CLASS from within the overloaded method? (By the way, yes, my unique is a METHOD of my class, not a subfunction. I need it to be callable by everyone.)

Thanks,
Mason

Tags for 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