Prev: imwrite image in an array
Next: CONVERT
From: Cygnine on 9 Feb 2010 15:15 Well, nobody likes a double-post, but it turns out that dbstack didn't quite solve my problem. (Or at least I don't know how to use it to solve the problem.) If I run [s, index] = dbstack at the command line, s has length 0 and index is 1. Fine. If copy+paste that into a script and run it, then s has length 1 and index is 1. Fine. If I copy+past that into a function and run it *from the command line*, then s has length 1 and index is 1. Fine. If I run the aforementioned function *from a script*, then s has length 2 and index is 1. Not fine. I want to be able to say from the last two instances that the workspace from which the function was called is the base workspace. I don't see how I can determine that from the given information of dbstack. How do I ask dbstack to tell me that the enclosing m-file is a function or a script? I don't think the "file" or "name" field of the struct s give me that information. In particular, I don't understand what "index" is supposed to be. The help file for dbstack states that it's the "current workspace index". I cannot find any (other) reference to "workspace index" in Matlab's product help or from Google. So either dbstack does not really help me entirely,
From: Doug Schwarz on 9 Feb 2010 16:09 In article <hksfop$fuj$1(a)fred.mathworks.com>, "Cygnine " <cygnine(a)remove.this.gmail.com> wrote: > Well, nobody likes a double-post, but it turns out that dbstack didn't quite > solve my problem. (Or at least I don't know how to use it to solve the > problem.) > > If I run > > [s, index] = dbstack > > at the command line, s has length 0 and index is 1. Fine. > > If copy+paste that into a script and run it, then s has length 1 and index is > 1. Fine. > > If I copy+past that into a function and run it *from the command line*, then > s has length 1 and index is 1. Fine. > > If I run the aforementioned function *from a script*, then s has length 2 and > index is 1. Not fine. > > I want to be able to say from the last two instances that the workspace from > which the function was called is the base workspace. I don't see how I can > determine that from the given information of dbstack. How do I ask dbstack to > tell me that the enclosing m-file is a function or a script? I don't think > the "file" or "name" field of the struct s give me that information. > > In particular, I don't understand what "index" is supposed to be. The help > file for dbstack states that it's the "current workspace index". I cannot > find any (other) reference to "workspace index" in Matlab's product help or > from Google. So either dbstack does not really help me entirely, Try nargin('junk'). If junk.m is a function it returns the number of input arguments. If junk.m is a script you get an error. By the way, are you familiar with packages in MATLAB? You can package a bunch of functions in a directory named with a +. For example, if there is a directory, '+mycode', on the MATLAB path and it contains fcn.m, you call that function with mycode.fcn() and there is no conflict with any other fcn.m on your path. I know it's not the same as Python and its import statement in that you have to use the full package name, but maybe it's better than the non-standard kludge you're working on now. Just a thought. -- Doug Schwarz dmschwarz&ieee,org Make obvious changes to get real email address.
From: Matt J on 9 Feb 2010 16:51 Doug Schwarz <see(a)sig.for.address.edu> wrote in message <see-99AAD7.16094609022010(a)news.frontiernet.net>... > By the way, are you familiar with packages in MATLAB? You can package a > bunch of functions in a directory named with a +. For example, if there > is a directory, '+mycode', on the MATLAB path and it contains fcn.m, you > call that function with > > mycode.fcn() > > and there is no conflict with any other fcn.m on your path. However, if inside mycode.fcn() a call is to be made to another function fnc2() which is also in the +mycode package, then it too must use the syntax mycode.fcn2() and so in with every function call. As well as being a cumbersome syntax, this means that, if you are given a library of mfiles that was not initially written as a package, it is very tedious to convert it. This is one of the main reasons I resorted to my FEX tool.
From: Matt J on 9 Feb 2010 17:28 "Cygnine " <cygnine(a)remove.this.gmail.com> wrote in message <hks195$fpc$1(a)fred.mathworks.com>... > To solve this, I've created a class FunctionNode, and each instance of FunctionNode corresponds to an m-file in a package. Now I've overloaded subsref for this object so that using function calling syntax, i.e. f(blah1, blah2), works exactly the same way as a function handle. However, going through Matlab's internal processing structure of overloading subsref appears to take a considerable amount of time (and my codes call lots of FunctionNodes multiple times). =================== Even if that is true, by the way, it probably only means you are committing the classic MATLAB sin of trying to do a for-loop over computations that are better off being vectorized. For the overhead of going through subsref to be significant, the rest of the computations done by a single call to f(blah1,blah2) would have to be lightning fast. But we never do a loop over lightning fast function calls in MATLAB. We make one function call in a vectorized way. Consider the following class, for example, which is essentially a subsref-driven function handle to the sin() function classdef myClass methods function out=subsref(ob,S) out=sin(S.subs{:}); end end end Now take the data X=rand(3000); FancyHandle=myClass; and compare the following timings. Essentially, there's no difference. >> clear z, tic; z=sin(x);toc Elapsed time is 0.287017 seconds. >> clear z, tic; z=FancyHandle(x);toc Elapsed time is 0.261119 seconds.
From: Cygnine on 9 Feb 2010 18:15
Doug Schwarz <see(a)sig.for.address.edu> wrote in message > Try nargin('junk'). If junk.m is a function it returns the number of > input arguments. If junk.m is a script you get an error. Hm, I'm afraid I don't follow your line of logic. If I'm inside a function, how do I use this to gather information about the number of input arguments in the caller? I suppose I could do something with an evalin statement by grabbing the function name from dbstack. However, as I mentioned before, with the Pythonic methods, I (often) rename function handles locally to names that are different from the function name inside the file -- I don't think dbstack will jive with this. And `nargin' run at the command line or in a script returns garbage (that could turn out to be an integer). > By the way, are you familiar with packages in MATLAB? Yes. But for the reasons Matt J specified (and others), I prefer not to use it. > I know it's not the same as Python and its import statement in that you have to use > the full package name, but maybe it's better than the non-standard > kludge you're working on now. Just a thought. You have a valid point about the Matlab packages functionality being built-in already. However, from my (admittedly biased) point of view, my method is much easier to work with and has serious advantages over Matlab's packages with few drawbacks (the current concern being one of them). The concern of the current thread is really quite ancillary and almost cosmetic. "Matt J " <mattjacREMOVE(a)THISieee.spam> wrote in message > Even if that is true, by the way, it probably only means you are committing the classic > MATLAB sin of trying to do a for-loop over computations that are better off being > vectorized. For the overhead of going through subsref to be significant, the rest of > the computations done by a single call to f(blah1,blah2) would have to be lightning > fast. But we never do a loop over lightning fast function calls in MATLAB. We make > one function call in a vectorized way. But it is not always possible to 'vectorize' code (e.g. if operations are inherently sequential). I always make pretty honest efforts to vectorize all code I write, but sometimes it's not possible (and sometimes it's not worth it). This happens often enough that I observe (significant) time penalties if I use a class instance to call a function rather than the handle directly. Besides, many of the codes I write do indeed perform fancy operations by creative uses of lightning-fast precompiled BLAS routines that drive Matlab's array backend; for moderately-sized arrays, the subsref call could double the required time. That's not acceptable to me. And just as a comment: I'm not actually sure it's subsref that is the time restriction. It could just be that Matlab implementation of classes in general just isn't fast. |