Since MATLAB has had the capability to publish M-files, we have seen publishing being adopted at many educational institutions. And there is a variety of ways for you
to find out just what's been published out there, perhaps so you can leverage it.
But you can just poke around and find a lot of good stuff up and down this list. Here's a really good site I noticed recently
for teaching Calculus.
Who Publishes?
I’ve been very happy, as I look at the web demos coming in, to see that published M-files are being used by professors more
and more. Some of them are lovely and well made. Here are a few favorites of mine:
And sometimes they’re even used for exams such as this site.
Do You Publish from MATLAB for School?
If you use publishing for some aspect of school work, post here and please post 1 (one) URL to your own best site. Please also post a URL to a site (new to you perhaps) that uses |publish
and you think has material potentially useful to you and others.
This is a repost of an article I wrote early on in this blog's history. Since there continue to be frequent questions on the MATLAB newsgroup regarding processing a set of files, I thought it would be worthwhile recapping this post.
I should start a clean workspace and with no WAV-files in my blog publishing directory.
clear all
delete *.wav
Problem Statement
Suppose I want to convert sounds stored in MATLAB MAT-files to files saved in WAV format for Windows. Without explictly hardcoding
in the filenames, here's a way to proceed.
matfiles =
6x1 struct array with fields:
name
date
bytes
isdir
datenum
Check out the Files
We can see from the length of matfiles that I have 6 MAT-files.
load(matfiles(1).name)
whos
Name Size Bytes Class Attributes
Fs 1x1 8 double
matfiles 6x1 2576 struct
y 13129x1 105032 double
Loading the data places the MAT-file contents into a structure from which I can extract the information I need and write it
back out. The sound files that MATLAB ships with store the data in y and the sampling frequency in Fs. Let's look at the first signal.
N = length(y);
plot((1:N)/(N*Fs),y), title(matfiles(1).name(1:end-4))
Loops over the Files
for ind = 2:length(matfiles)
data = load(matfiles(ind).name);
wavwrite(data.y,data.Fs,matfiles(ind).name(1:end-4));
end
Warning: Data clipped during write to file:gong
Warning: Data clipped during write to file:splat
Warning: Data clipped during write to file:train
I'll double-check the last file I just read in and wrote out. ind is still set despite no longer being in the for loop. Let's check both the frequencies and the signals themselves.
The data stored in the WAV-file is NOT exactly the same as that stored in the MAT-file. Reading the help for wavwrite gives some insight; the data in the WAV-file, by default, is stored as 16-bit data vs. MATLAB's standard 64-bit double.
Thoughts?
Does it confuse people here that I don't worry about vectorization? Any other thoughts on this topic?
We have heard repeatedly over the years that users would like a tool to help clean up the workspace by choosing selected variables
to retain. The function clear, has logic allowing you to clear a selection of variables readily, but it's a bit harder to retain a collection using clear.
The function clear, with the all qualifier, can clear just about everything in MATLAB: variables, functions, MEX-files, breakpoints, Java packages import
list (from the command prompt). To additionally clear classes, use clear classes.
Debug Gotcha
clear all clears all breakpoints as well as the workspace, and everything else that isn't nailed down (or perhaps mlocked ). This is a frequent source of confusion for people when they are trying to debug code. If the code being debugged issues
a clear statement, the breakpoints get cleared and you could be left with a temporary mystery until you chase down the code doing
the clearing.
How to Keep Variable Selection
Use clear with -regexp to remove variables selected from memory.
Use clearvars -except to retain specific variables in the workspace.
Here's an example of clearing all the variables except those that start with q (the 17th letter of the English alphabet).
Google recently made a splash about its e-api-tools-for.html latest language tools. Translating one computer language to another is useful but passé. But suppose you could translate a computer language to
a human language: MATLAB -> English and English -> MATLAB. Type in your word problem and get the code instantly. It could
help you with your MATLAB accent, or, if English is not your first natural language, you might learn some vernacular from
MATLAB's interpretation.
In particular, such a translator might be good at recognizing and translating common phrases. Here are but a few of the phrases
the translator (under development) gets right.
eye(newt), from Shakespeare's hags
ceil(approval), from Good Housekeeping
wait(theWorld)
angle(repose), an excellent book by Wallace Stegner
balance(power), axis(power), etc., assuming you've pre-empted the function with your own variable or function, of course
gallery(art)
length(day) (day has the same caveat as power above)
residue(ashes)
sign(theTimes)
sound(music), thanks to Julie Andrews, among others
theTotal = sum(theParts)
Notice how the parentheses are pronounced in English : "of".
Command Duality
The MATLAB translator understands command-function duality and the nuances of English. It would not do to write the last example as
wait theWorld
Nor would
polar bear
be okay because polar doesn't take a character array for its first argument.
However, it would be okay to say
global warming
median strip
What Are Your Translation Needs?
Sure, we will translate between MATLAB and other languages once we have the English version ready to go. And, I should warn
you that Steve Eddins from the Steve on Image Processing blog has been working for years on mindread.m as well. Beyond these two obvious needs, what other translation needs do you have? Or other thoughts on this post? What
about MATLAB poetry (Tim?)? Let me know here.
Recently someone at MathWorks asked me how he could automate the renaming of a bunch of M-files containing underscores ('_') in the names with derived names that removed the underscores and used camelCasing instead. You may have similar name manipulation operations you need to perform.
function y = camelCase(x)
%camelCase Convert name with underscores to camelCase.
% find the underscores
indall = find(x=='_');
% figure out where consecutive _ are
% and remove all but the last
consec = diff(indall)==1;
ind = indall;
ind(consec) = [];
y = x;
y(min(ind+1,end)) = upper(y(min(ind+1,end)));
y(indall) = '';
I first find all the underscores. Then I look for consecutive ones since I really only want the last one in each sequence,
since it's the following character that I want to turn into upper case. That is, if a following character exists! So I have to check for that too. I then have an array of indices to upper case (though I
allow myself to uppercase _ at the end if it's the last character so I don't have to lengthen my input array; upper('_') is the same as '_'). Now, I go back and use the original indices pointing to all the instances of '_' and remove them. Voila!
History Lesson
And then I got some pangs, because I am well aware that MATLAB supports regular expressions. First some history. Did you know that Stephen Kleene, an American mathematician, was the inventor of regular expressions? He has also been credited with developing a very approachable
proof to Gödel's incompleteness theorems. And some punster then said, "Kleeneliness is next to Gödeliness".
Using regexprep
My friend, colleague, and regexp guru, Jason Breslau gave me the regexprep solution to the problem. Using the same names as before, I next show you Jason's magical 1-line expression, producing the
same output as my M-file above.
for name = names
disp(regexprep(name{1}, '_+(\w?)', '${upper($1)}'));
end
My code is still easier for me to understand, and I conclude from that that I should spend some time trying to master regular expressions.
In addition, the regular expression code requires no temporary variables, some of which could be large if the input string
is long enough. It also occurs to me that regular expressions are a topic worthy of students learning well in college. What
do you think? Let me know here.
In the past, when you opened a file in a MATLAB program, you had to keep track of it so you could close it under all possible
conditions, i.e., if reading or processing failed, worked partially, or worked perfectly. You could achieve this using the
catch block after a try. But you still might have to know before closing the file if everything you wanted to do was complete. Code could easily
get awkward and buggy if there were lots of code paths to watch out for. With R2008a, you can use the onCleanup class to help you out more cleanly.
Example Code - Manage Open, Close, and Errors Using try/catch
Now let's look at another version of the code that will close the file it opens before returning.
type openImageFile1
function openImageFile1
% openImageFile1 Open/process file while ensuring file is
% closed on finish.
try
fd = fopen('pout.tif');
if fid == -1
error('LS:NoImageFile','no such file')
end
doMoreHere(fd);
catch Ex
disp('Can not read file')
end
if fid ~= -1
fclose(fid);
end
You can see that, even with try/catch, since I always want to close the image file, I have some extra logic at the end of the file. And I have to be careful to
know whether the error occurs because the file was never opened, or if instead the error occurs in later processing.
Example Code - Use onCleanup to Ensure File Closes
Here's a file roughly equivalent to the first one, but it ensures that the image file is closed when the function is finished
running.
type openImageFile2
function openImageFile2
% openImageFile2 Open an image file for further processing.
% Note: this doesn't do what you want, since the file will
% be closed after completing and the file identifier won't
% be active for use upon completion.
fd = fopen('pout.tif');
C = onCleanup(@()fclose(fd));
To see that this works we first check that no files are open, run the function, and make sure that no files are open afterwards.
Example Code - Use onCleanup and Process After Opening the File
Let's see the next version of the file.
type openImageFile3
function fd = openImageFile3
% openImageFile3 Open an image file for further processing.
% Note: this doesn't do what you want, since the file will
% be closed after completing and the file identifier won't
% be active for use upon completion.
fd = fopen('pout.tif');
C = onCleanup(@()fclose(fd));
This function returns the file identifier, but as we'll see, the file is closed once the function returns. This means that
any processing/reading we were planning to do with the file after calling the open function will not work (since the file
will no longer be open).
Even though fid is returned from the function call, the file is no longer open. This is because the onCleanup object C is cleared from existence once openImageFile3 completes execution.
Example Code - Use onCleanup and Process and Close File on Completion
Here's the last version of the file for this blog. As long as you call it with 2 outputs, you are good to go.
type openImageFile4
function [fd, C] = openImageFile4
% openImageFile4 Open an image file for further processing.
% Note: this does what you want, provided you call the
% function with both output arguments. When you are done
% cleaned up and the onCleanup object will trigger the file
% closing.
% Don't even open file if function isn't called with 2 outputs.
if nargout < 2
error('LS:MustHave2Outputs','must call with 2 outputs')
end
fd = fopen('pout.tif');
C = onCleanup(@()fclose(fd));
This version returns the file identifier and the onCleanup object. Once you have processed your file, simply clear the onCleanup object and the file will close.
To see how this might work, we call it from our function that does the processing.
type run4
function y = run4
% run4 processes an image file.
[fid,C] = openImageFile4();
blocksize = 100;
y = [];
while something
dat = fread(fid,count);
y = doSomething(y,dat);
something = update(something);
end
You can see that run4 calls openImageFile4, and then does the required processing. Because C will vanish once run4 completes, the file will be closed.
Other Uses?
The onCleanup object allows you to more cleanly manage resources such as closing files, closing windows (e.g., last week someone mentioned
managing instances of waitbar), managing switching directories. What uses do you foresee for the onCleanup object in your work? Let me know here.
The first 2008 semi-annual release of MathWorks products is now available, R2008a. Over the next few months, some of my blog articles will highlight new features.
Do you ever need both the minimum and maximum values on the same data? Sometimes I do, for example, when I want to tweak the
limits of a 2-dimensional plot. So I was wondering whether that is a common task? I also wondered what the overhead is in
calling min and max separately, instead of scanning through the data once, looking for both the lowest and highest values.
I will explore this idea by creating my own simplified versions of max and min, working only for real vector inputs, not checking for NaNs, and not doing any error checking. Clearly, the code I show
is not meant for production but to get to the heart of the algorithm.
function xmin = mymin(x)
%MYMIN Minimum value of real vector input.
% MYMIN is a simplified version of MIN that
% finds the minimum value for
% real-valued vector. NaNs are not treated.
xmin = Inf;
for ind = 1:length(x)
if x(ind) < xmin
xmin = x(ind);
end
end
Test mymin Function
Now I compare the result from mymin to the built-in min function in MATLAB.
Now let me show you my combined function myminmax that loops through the data the same way mymin and mymax did, but does both calculations in the loop together.
type myminmax
function [xmin, xmax] = myminmax(x)
%MYMINMAX Extreme values of real vector input.
% MYMINMAX is a simplified version of MIN and
% MAX combined and finds the
% minimum and maximum values for real-valued vector.
% NaNs are not treated.
xmin = Inf;
xmax = -Inf;
for ind = 1:length(x)
if x(ind) < xmin
xmin = x(ind);
end
if x(ind) > xmax
xmax = x(ind);
end
end
First, let's check that we get the expected results.
To compare the times, let's look at the sum for the times calling the individual functions vs. calling the combined one.
t2 = timeMin+timeMax;
format long
disp('Adding separate times Combined Time')
disp([t2 timeMinmax])
Adding separate times Combined Time
1.495988735998570 1.061442445897453
Reset format to default
format short
Worth It?
Is it worth having a combined function for min and max from a speed point of view? I don't know. It depends on many things, including how often it's needed, and if finding the
min and max values is one of the dominant time consumers in the overall algorithm. What do you think? Let me know here.
I'm very pleased to announce that we have a new blog on mathworks.com. We now have Seth on Simulink. Please read his blog for insight into Simulink, how to use it, what are the new features, etc.
Recent Comments