Showing posts with label matlab. Show all posts
Showing posts with label matlab. Show all posts

Saturday, May 24, 2008

External commands in MATLAB

For some time now, I have often wondered why MATLAB highlighted text starting with a ! in a different colour. I thought nothing of it until recently when I was, as always, randomly entering code into MATLAB and had accidentally put a exclamation mark in the command window (I can't remember the exact reason why I was using exclamation marks). The result was quite interesting: it sent the command to the command interpreter outside of MATLAB which, of course, flagged this as an error. In seeing this, I stopped what I was doing and started to play about with this newly discovered shortcut.


My first command was !bash which, being in Linux, should run the BASH shell... which it did. I could then use MATLAB as a glorified terminal window. Whilst in BASH, I decided to check for updates for the machine which would require me to use sudo followed by the update command (and as I use Ubuntu, that's simply turns out to be sudo apt-get update). As always (with the exception of doing this in MATLAB), I was prompted for my password. Interestingly, MATLAB behaved like the terminal window and didn't display my password which normally happens should one Telnet their POP3 server (a hobby of mine). I guess this would be due to a so-called seamless "pipe" between MATLAB and, in this case, BASH.


From here, one can then go a step further an build m-files that run external commands. Of course, there's the issue of platform dependency here (mainly for the UNIX group) but one can work around this issue. A nice feature (at least in the UNIX version) is the fact that ! commands run in the current working directory (try !pwd and await a response) which means navigation isn't a problem. One minor niggle that I haven't been able to resolve just yet is trying to take a result from the external command without resulting to taking output manually using the command > output.log method.


So let's create something that works out what platform we're running on from within MATLAB and obtains the flavour of Linux using Linux command uname



if isunix

% In Unix, determine OS type

!uname -s > unixname.txt

% Now read this file:

fid = fopen(unixname.txt, 'rt');

if feof(fid) == 0 % Determine if at end of file

osname = fgetl(fid); % Get line

else

disp('File ended early');

end

elseif ispc

disp('I''m in MS Windows');

else

disp('Impossible: You''re not running either Windows or UNIX?');

end


Hopefully you are able to see the potential here in executing external applications based on what operating system environment is currently being used. Both Windows and UNIX support the command > output.log method (which you may remember from the Queue system). In fact, I frequently create script files using a combination of echo and the "append" verb >> where I can get away with it.


Read more on this article...

Sunday, May 11, 2008

LaTeX in MATLAB

Not too long ago, I was entering random commands into MATLAB (read: I was bored, so wondered if certain commands existed). I finally came across a few "games" which would have a practical side to them:


  • xpbombs for a Minesweeper equivalent

  • fifteen for a puzzle game

  • sf_tictacflow for naughts and crosses/Tic-Tac-Toe

  • sf_tetris for Tetris



It was after this search, I wondered into the LaTeX command which was cunningly called latex. This command makes it possible to port equations and matrices from the MATLAB workspace to your LaTeX document.


The latex command makes use of the Symbolic Toolbox which is available with MATLAB (providing you have the appropriate licence). The Symbolic Toolbox can easily calculate integrals and Taylor expansions algebraically (however it doesn't show workings if you're looking for the intermediate steps). It can even convert matrices and vectors into LaTeX providing you convert the matrix or vector into a symbolic object first.


To convert an ordinary double object into symbolic object, one simply has to encapsulate the double object in a sym environment, i.e. output = sym(x). The outputted object can then be processed for LaTeX conversion using the latex(output). In the case of matrices, the output even puts the dynamic brackets that resize depending on its contents (i.e. the \left[ and \right]) which, of course, can be changed to whatever you want once its imported into your document.


Taylor expansions? No problem. Simply assign a variable like x to be symbolic by either typing syms x or x = sym('x'), then output = taylor(exp(x)) should you wish to see the Taylor expansion of e^x. As before, LaTeX-ify the output by using latex(output) which you can then copy into your document.


If copy and pasting is getting a little too much, you could use the inbuilt copy command which will move the output into clipboard for you. All you'll have to do then is paste the contents of clipboard into the application of your choice. Easy. Here's the code: clipboard('copy', latex(output)).


What obviously comes next is a quick script that does this all for you depending on the input. Like many of my scripts, I simply append the word "it" to the original function name; so in this case I created a latexit.m file:


function output = latexit(input, copyToClipboard)



output = [];



if nargin == 1

copyToClipboard = true;

elseif ~islogical(copyToClipboard)

warning('Second argument should be logical. Assuming value is false');

copyToClipboard = false;

end



if isa(input, 'sym')

% Symbolic object

output = latex(input);

else

% Another type of object

try

output = latex(sym(input));

catch

error('Could not process input. Try converting object to a symbolic form manually and then reprocess');

end

end



if copyToClipboard

clipboard('copy', output);

end


That should be it. A script file that could convert matrices and output them as LaTeX in addition to moving the LaTeX code into the clipboard (which can be disabled by supplying false as the second argument). If you were really lazy, you could wrap the LaTeX code in an equation environment too, but there's little point in doing that here.


Further investigation into how this works reveals that it goes deeper than the Symbolic Toolbox as it turns out it uses the Maple engine to turn the symbolic object into LaTeX output. Why reinvent the wheel when someone's already done a fine job?


Read more on this article...

Tuesday, May 6, 2008

Linux, Compiz and MATLAB

Recently, a new version of Ubuntu was released and, being an Ubuntu user, I installed this latest version. For some time now, I've not been able to run MATLAB with the fancy window graphics switched on without displaying an almost blank (grey) screen. That is until finding a helpful post on the Ubuntu Forums.


For those that don't know, the "fancy window graphics" within Ubuntu and, from what I gather, other distributions of Linux are produced by a component known as Compiz which is capable of producing many interesting effects such as water ripples, a desktop cube plus many more effects.


The reason why MATLAB displays a grey box when Compiz is enabled is down to the way Java attempts to interact with window managers. According to one post I read, the problem arises due to the Java toolkit code assuming that all window managers re-parent windows. If a window manager (such as Compiz, Compiz Fusion, etc.) is running, then the Java toolkit waits for new windows to be re-parented before it starts handling certain events on them. Since Compiz and other window managers do not re-parent windows, the Java-based applications end up waiting forever.


There was a time, a year or two ago, where the fix consisted of altering the Java source which was awfully messy and didn't work for every distribution of Linux. This time, there's a better workaround which doesn't involve the AWT_TOOLKIT patch (which I, personally, could never get working). This one is a simple and makes use of the latest version of Sun's Java (as Sun eventually got around to patching this problem). MATLAB, by default, is shipped with its own Java Virtual Machine (JVM) and so is independent of the version that exists (or doesn't exist) on your workstation. We therefore have to override this information by typing in the following within the Terminal:


export MATLAB_JAVA=/usr/lib/jvm/java-6-sun/jre/


This code simply exports the variable MATLAB_JAVA where it then exists for the lifespan of the Terminal window. Note that you should replace the path I've used to the latest Sun version of the Java Runtime suite.


From here, one can type in matlab -desktop or, simply, matlab (I am the proud owner of a broken installation which requires me to enter the -desktop argument). Typing this in every time you want to open up MATLAB could be described as arduous, so the creation of a script file that could do this for you sounds quite enticing.


If, like me, you enjoy creating random scripts that do numerous things (like connect via SSH with key authentication), you would probably have a folder where you store all your scripts. If not, it's not too early to start: create a new folder within your home folder by typing mkdir bin. If you're lucky, this should be added automatically to your $PATH variable for you (as it's defined within your .profile within your home directory. Next, type in cd bin where bin is the location to your script files. From the top of your head, think of a name to call MATLAB which will load everything for you; I'll pick matlabgo. Once you've decided, continue and replace matlabgo with the name of your choice. Type:


echo "export MATLAB_JAVA=/usr/lib/jvm/java-6-sun/jre/" > matlabgo

echo "matlab -desktop" >> matlabgo

chmod u+x matlabgo


So we've basically created the file (without use of any editor, mind you) and then changed the permissions of our link so that we can execute (and, hence, use) it. You should now be able to type in matlabgo into the Terminal and even link up shortcuts that use this script file.


For those that are interested in my source, head to: http://ubuntuforums.org/showthread.php?t=635142 for more information.


Read more on this article...

Saturday, February 2, 2008

Simple BASH-based Queue System

I'm rather new to the entire Linux shell scripting world. After a brief look into BASH (Bourne-Again Shell), the default shell used in Ubuntu which I have installed on my office machine, I set about on my next mini-project.


Whilst I have seen many examples of BASH in use (like drawing ASCII circles, etc.), I thought that I should develop something seemingly useful (seeing that the office machine isn't used for anything particularly useful, except experimenting and Microsoft Office on the Windows partition for those that absolutely insist on sending attachments in MS Office formats). Anyway (I digress), I planned to create a workhorse machine which would perform all my MATLAB simulations, etc. automatically. Actually, it'd be a cheap (and slimmed-down) version of the University's grid service: Iceberg


So with some sticky-back plastic, I set about sorting out SSH (Secure Shell) availability on Ubuntu such that I could "dial in" to the office machine, submit a job and log-out (SSH will allow you to establish a remote shell and, with the X-server, you can also receive graphics/windows allowing, essentially, a complete remote working solution). With SSH set for a single (restricted) account, I altered the account's home directory access control such that the queue manager account would have read and write access to files (otherwise, no tasks will ever be started, let alone completed). So with SSH working and an account for working remotely, it was now possible to build the foundations of the queue manager.


Submitting Tasks/Jobs


The first step was to establish a path that both tasks could be queued to and script files related to the queue system could be stored. I chose /home/queue/ so as not to cause any grief to the already-fudged system files and directories I had been experimenting with on previous occasions. The first task problem to overcome was how to create these task files such that the queue manager could execute each one consecutively. The simplest solution was to save every task as a script file within the common queue directory. To overcome the problem of multiple tasks with the same name, each task/job was given a unique Job ID which would, in effect, also act as a receipt. The resulting submitjob script file was created (again, my apologies for the formatting issues):


#!/bin/bash
#
# Used to submit jobs to the Queue Manager
#
# Version: 0.1 (24th October 2007)
# Author: Andrew
#

# Generate a job ID
jobid="`date +%y%m%d%H%M%S`-$RANDOM"

# Check to see if a parameter has been given
if [ $# != 1 ]
then
echo ' ERROR: Job to submit not specified'
echo ' '
echo " Usage: `basename $0` [file to submit]"
echo ' '
exit 1
fi

# Check to see if the file does not exist
if [ ! -e $1 ]
then
echo " ERROR: The file \"$1\" does not exist."
exit 1
fi

# Rename the current file
mv $1 ${jobid}.job

if [ $? -eq 0 ]
then
# Copy the job file
cp ${jobid}.job ${QUEUEPATH}
if [ $? -ne 0 ]
then
# Error copying to queue path
echo " ERROR: Unable to copy ${jobid}.job to ${QUEUEPATH}"
exit 1
fi
else
echo " ERROR: Unable to create new job file with ID: ${jobid}"
exit 1
fi

echo ' '
echo " You have been assigned job ID ${jobid}"
echo ' ************************************'
echo ' '
echo ' Please make a note of your job ID as you will need this'
echo ' to stop your job and/or know when your job has finished'
echo ' '
echo ' As a reminder, the job submission file has been renamed'
echo " to the corresponding job ID ${jobid}.job. This file"
echo ' can be safely deleted as the job is now in the queue.'
echo ' '


Note the use of the global variable QUEUEPATH. This is set to the queue path whenever a Terminal session is created which means the path can be updated or altered at a later date without the need to change all the source files). To distinguish job files from other types of files, I skilfully appended the file extension .job to all task files.
So now we've submitted a job file, we'd preferable want to be able to do some things with it, so we move onto the queue manager itself.


The Queue Manager


The queue manager's job, as its name implies, is to manage jobs by checking for new script files to execute and... well, execute them. To get a fair idea of what to run, a simple directory listing would do the job which could then be recorded to a text file. If the file was empty, it should act idle and await a task (without hogging processor cycles so as not to hinder other unproductive work) whereas if there were entries within the list of job files, it should execute them consecutively. This immediately screams the need for a loop of some description and, due to our lack of knowledge on how many files there will be, we'd need to use a do...done loop. This should also ring some alarm bells as we'd need some kind of condition (other than Ctrl + C) to terminate the queue manager. Whilst I could invest time in creating an intelligent solution to this problem, I opted for another file creation system (namely a file called quit.job which would terminate the loop should the queue manager see this file).


Anyone could then technically create a file called quit.job and terminate the queue manager (i.e. sabotage... although "who?" remains a good question and only fuels my paranoia), so the owner would need to be determined. Luckily, Linux has a utility called whoami which, unlike the Jackie Chan movie, determines who's the current user (great for those that forget who they are... like the Jackie Chan movie). This is also embedded into the BASH if...fi statements as the tag -O filename.ext which makes the task of identification extremely easy. Additionally, the ability to notify the owner of task completion (and even when a job starts) can be done through the sendEmail program. This script file is included below (I have, however, altered the email address and SMTP mail server fields to minimise the risk of junk mail and a very unhappy University):



#!/bin/bash
#
# Basic queue manager for running jobs remotely.
#
# Version: 0.1 (24th October 2007)
# Author: Andrew
#

# Ensure a command to quit doesn't already exist
rm -f ${QUEUEPATH}quit.job

echo ' Queue Manager Initialising...'
echo ' '
echo ' Entering looping state...'
while
true # Loop forever
do
# Check to see if there are jobs
ls ${QUEUEPATH} | grep .job > ${QUEUEPATH}contents.txt
nextjob=`head -1 ${QUEUEPATH}contents.txt`
# Then check to see if there's something in this variable. If not, then there's not job to run
if [[ ! -z $nextjob ]]
then
# There's a job to run
echo "Job ${nextjob%%.job} Started"

# Extract notification information
notification=`fgrep "#$" "${QUEUEPATH}$nextjob" | tr "[:upper:]" "[:lower:]" | fgrep "notify" | head -1 | tr -d " " | cut -c10-11`

if [[ ! -z $notification ]]
then
# Extract email information
emailadd=`fgrep "#$" "${QUEUEPATH}$nextjob" | tr "[:upper:]" "[:lower:]" | fgrep "email" | head -1 | tr -d " " | cut -c9-50`

# Check to see if a notification should be sent at the start of the job
if [[ ( $notification = 1 || $notification = 3 ) && ! -z $emailadd ]]
then
sendEmail -f "my.email@ddress" -t "$emailadd" -u "Job ${nextjob%%.job} Started" -m "Hi,\n\nAs requested, this message is to inform you that job ${nextjob%%.job} started at `date`\n\nRegards,\n\nAndrew" -s "smtp.mail.server.address" -q
fi
fi

# Run the job in a new bash shell
bash ${QUEUEPATH}$nextjob

# Job complete tell user

if [[ ( $notification = 2 || $notification = 3 ) && ! -z $emailadd ]]
then
sendEmail -f "my.email@ddress" -t "$emailadd" -u "Job ${nextjob%%.job} Completed" -m "Hi,\n\nAs requested, this message is to inform you that job ${nextjob%%.job} completed at `date`\n\nRegards,\n\nAndrew" -s "smtp.mail.server.address" -q
fi

# Now Job is complete. Remove the file
rm -f ${QUEUEPATH}${nextjob}
echo ' '
echo "Job ${nextjob%%.job} Finished"

else
# There's no job to run

# In order to save the poor computer, sleep for 2 seconds
sleep 2
fi

# Need to check for the quit.job file and
# confirm that the owner is whoami
if [[ -e ${QUEUEPATH}quit.job ]]
then
if [[ -O ${QUEUEPATH}quit.job ]]
then
break
else
echo " Owner of file different to `whoami`. Removing file"
rm -f ${QUEUEPATH}quit.job
fi
fi
done

# If outside the main loop, the quit file exists.
# Need to delete the file and then inform user of
# the quit command
echo ' Quit file detected. The Queue Manager is shutting down...'
# Delete the file
rm -f ${QUEUEPATH}quit.job
echo ' Clean-up complete. Queue Manager finished.'


So there you have it. One queue manager completed. You may notice some rather odd goings-on with the email address system as it parses the header information from a task script file which would contain information such as the what type of notifications to send (when starting and/or finishing a job). I have also set a default time of 2 seconds before checking for new items in the queue should there be no jobs to execute in order to minimise CPU cycle wastage.


MATLAB?


As I mentioned earlier, my intention is to use the office machine as a workhorse that would, predominantly, run consecutive MATLAB simulations. MATLAB has the ability to run under a Terminal window (handy for those that dislike the memory hungry Java GUI in favour of the trusty (not to mention stable) Terminal window). This is possible thanks to the arguments -nojvm -nosplash -nodisplay which seem pretty self-explanatory. One thing to take note is that as the GUI is essentially disabled, no windows will appear (so forget using the plot feature in this mode - you're better outputting the contents into other interpretors like Python's matplotlib library which, in my opinion, is far more customisable (and, hence, more powerful?) compared to MATLAB's inbuilt plot function). So, courtesy of the Iceberg team, I give you the matlabjob script:


#!/bin/bash
#
# For running matlab jobs
#
help()
{
echo ' Usage: matlabjob matlab_script_file [output_file] '
echo ' '
echo ' This command runs the MATLAB script file in'
echo ' non-interactive, non-graphical mode'
echo ' '
echo ' if the output_file is not specified, output is directed to stdout'
}
if test -z "$1"
then
help
exit 1
else
if test -f "$1"
then
if test -z "$2"
then
matlab -nojvm -nosplash -nodisplay < "$1"
else
matlab -nojvm -nosplash -nodisplay < "$1" > "$2"
fi
else
echo "$1" "is not a file"
fi
fi


Create a job file


Creating a job file that conforms with the specification required by the queue manager is important and so, to facilitate the user in creating a compliant script file, a wizard was created. Now, whenever I hear wizard, I normally shudder (no, not childhood trauma as you'd expect) and this is mainly down to the fact that most wizards you see nowadays try to do everything for you (including mess up everything - I need no help in this area). In order to please the end user (i.e. myself and perhaps a few other people in the office I could force to use this system), I developed a wizard that could create a script file with minimum intervention. Yes, there are better ways to do this kind of thing (like create a GUI, take up memory and crash your system), but I wanted a complete BASH solution to my queuing woes (after all, isn't it just the British that queue? (I suppose mainly out of necessity really)). As you're probably wondering what the hell I'm talking/writing/typing about, here's the code:



#!/bin/bash
#
# This creates a job file which can be read by the queue manager
#
# Version: 0.1 (27th October 2007)
# Author: Andrew
#

# Custom function for extending path names
tolongpath() {
if [[ "$1" = /* ]]
then
echo "$1"
else
echo "`pwd`/$1"
fi
}

# Set version
version="0.1"

if [[ $# = 1 ]]
then
# There's only one argument
# Check to see if the file has the .m extension
if [[ "$1" != *.m ]]
then
# The parameter doesn't seem to be an m-file. It's probably a log
outputfile="$1"
fi
elif [[ $# > 2 ]]
then
echo 'ERROR: Too many parameters'
echo ' '
echo "USAGE: `basename $0` [matlab_script_to_run.m] [job_file.job]"
echo " NOTE: Both parameters are optional"
echo ' '
exit 2
else
# Check for a second parameter
if [ -z "$2" ]
then
outputfile="myjob.job"
else
outputfile="$2"
fi
fi

echo '# This file was created using the interactive tool' > $outputfile
echo "# called `basename $0`, version $version" >> $outputfile
echo "# Creation date: `date`" >> $outputfile
echo '# ' >> $outputfile
echo ' ' >> $outputfile

emailnotify="preq"
# Loop until we get a desired answer
while [[ "$emailnotify" != n* && "$emailnotify" != y* ]]
do
echo -en "Do you wish to enable email notification for your job? [y/n]: "
read emailnotify
emailnotify=`echo $emailnotify | tr [:upper:] [:lower:]`
done

# If email notification is required
if [[ "$emailnotify" == y* ]]
then
# Now perform email check:
while [[ "$emailnotify" != *@* || ( "$emailnotify" != *.co* &&
"$emailnotify" != *.ac.uk ) ]]
do
echo ' '
echo -e "Please enter a valid email address to which the"
echo -en "notifications will be sent to: "
read emailnotify
done
# Append this email address to the output file
echo "#$ email=$emailnotify" >> $outputfile

emailnotify=10
while [[ $emailnotify -lt 1 || $emailnotify -gt 3 ]]
do
echo ' '
echo 'Would you like notification when the job...'
echo '1. Commences'
echo '2. Completes'
echo '3. Commences and Completes'
echo ' '
echo -en "[Please select 1, 2 or 3]: "
read emailnotify
done

# Now add this to the job file
echo "#$ notify=$emailnotify" >> $outputfile
fi

# End of email section
# From here, we deal with just job that will be carried out

# Automatic mode...

if [[ "$1" = *.m ]]
then
echo ' '
echo 'MATLAB file detected as input variable. Automatically configuring setup file...'
if [[ -e $1 && -f $1 ]]
then
if [[ "$1" = */* ]]
then
# The file already has a path
echo "matlabjob \"$1\"" >> $outputfile
else
# Relative paths work okay
echo "matlabjob \"`pwd`/$1\"" >> $outputfile
fi
echo ' '
echo "Job file created successfully. You can now submit the job file \"$outputfile\""

# # Change the permissions within the directory
# $pathtochange=`readlink -f "$1"`
# $pathtochange=`dirname "$pathtochange"`
# chmod -R -f o+rwx $pathtochange/*
exit 0
else
echo "Could not find MATLAB file \"`pwd`/$1\"."
echo "Please ensure this file exists"
# Remove the output file as it's only longer required due to the failure
rm -f $outputfile
exit 2
fi
fi

# Manual mode...

# Ask the user if their job is MATLAB based
ismatlab="preq"
# Loop until we get a desired answer
while [[ "$ismatlab" != n* && "$ismatlab" != y* && "$ismatlab" != a* ]]
do
echo ' '
echo -en "Is the job MATLAB based (you need to have prepared a m-file)? [y/n/(a)bort]: "
read ismatlab
ismatlab=`echo $ismatlab | tr [:upper:] [:lower:]`
done

# Check input
if [[ "$ismatlab" = a* ]]
then
# Request to abort received
exit 1
elif [[ "$ismatlab" = y* ]]
then
# MATLAB will be used

# Tell the user the shortcut that can be used - currently only available for .m files
echo "HINT: You can use \"`basename $0` [matlab_script_to_run.m] [job_file.job]\""
echo " to quickly create a Job file. You will then only be prompted for"
echo " email notifications."
echo ' '

ismatlab="preq"
# Loop until we get a desired answer
while [[ "$ismatlab" != n* && "$ismatlab" != y* ]]
do
echo ' '
echo -en "Do you wish to take any MATLAB output to a file (for debugging)? [y/n]: "
read ismatlab
ismatlab=`echo $ismatlab | tr [:upper:] [:lower:]`
done
if [[ "$ismatlab" = y* ]]
then
# Take the name of the filename
echo ' '
echo -e "Please enter the name of the file you wish to save the output to: "
read logoutput
fi

# Now to get the MATLAB script from the user
while [[ ( "$matlabfile" != *.m && ! -e $matlabfile ) || -d $matlabfile ]]
do
echo ' '
echo -e "Please enter the filename of the script (including the .m extension): "
read matlabfile
done

# Now check the path
matlabfile=`tolongpath "$matlabfile"`

# Check to see if an output should be taken and write the necessary line
if [[ -z $logoutput ]]
then
# No log output
echo "runmatlab \"$matlabfile\"" >> $outputfile
else
logoutput=`tolongpath "$logoutput"`
echo "runmatlab \"$matlabfile\" \"$logoutput\"" >> $outputfile
fi

# # Change the permissions within the directory
# $pathtochange=`readlink -f "$matlabfile"`
# $pathtochange=`dirname "$pathtochange"`
# chmod -R -f o+rwx $pathtochange/*

# Finally, there's no need to continue running the script, so exit
exit 0
fi
# Ask the user whether a script file will run

isscript="preq"
# Loop until we get a desired answer
while [[ "$isscript" != n* && "$isscript" != y* ]]
do
echo -en "Has your job been created as a BASH-compatible script file? [y/n]: "
read isscript
isscript=`echo $isscript | tr [:upper:] [:lower:]`
done

# If email a BASH script will run is required
if [[ "$isscript" == y* ]]
then
# Script bash script to run. Which script?
while [[ ! -e $scriptfile || -d $scriptfile ]]
do
echo ' '
echo -e "Please enter the filename of the script (including the extension, if any): "
read scriptfile
done

# We now have a script file. It should be checked, but, on good faith,
# we assume file is okay

# Check the path and should it be a relative path, put it into its longer context
scriptfile=`tolongpath "$scriptfile"`

# Now add the line to the job file. There may be other arguments
# that could be added to the job file to customise the bash window
echo "bash \"$scriptfile\"" >> $outputfile

else
# No script will run. Nothing left to do
echo 'Create Job script finished. Nothing else to do.'
echo 'No job information was created - just a header.'
echo "Job file created as $outputfile. Add commands to the end of this file"
fi


So there you have it. The createjob script has been designed for MATLAB scripts in mind (although it will run other types of script files) in order to make that process easier (otherwise, users would be required to enter the corresponding MATLAB arguments and, should they forget, my office machine will have opened instances of MATLAB in GUI mode which could seriously cause some problems).


Other files


There exist other files that enable the remote user to view items within the queue and delete items from the queue in addition to the utility that ends the queue manager. None of which I will go into detail as they're simple script files, so I'll only say that they exist (and work).


Conclusion


Current statistics show that nobody is using it and I haven't any simulations to run just yet... not only that but Iceberg was recently upgraded such that the potential user(s) I had in mind will want to use the more powerful resources available to them... that is until I create a multi-CPU queue system which will happen as soon as I get my hands on a redundant computer within the office...


I should also mention the fact that the above has undergone a few revisions which aren't shown here - they're relatively minor changes, but has made the "experience" slightly better. Everything you see above was designed and implemented over the course of three days (I make that clear otherwise it would appear no academic work is done throughout my work week - a fair comment to make). Additionally, as with all small print, I take no responsibility for any damage to your office computer (or mine come to that matter) should you go about implementing the above.


Read more on this article...

Plotting in MATLAB

Further searching in the murky depths of MATLAB’s documentation revealed some useful information regarding the plot function. Whilst it may be common knowledge that plotting is fairly simple, there are some nice additions that can be made to a default-style plot that can enhance its appearance.

  1. The first is the popular grid function. It’s simple and does what it says - adds a grid to the plot. Most people either state grid or grid on, but if you fancy being different, try grid minor
  2. The second is the box function. Again, its name suggests that it adds (or removes) the box around a plot. Again, it’s possible to enter box or box off. For most, if not all, plots the box function removes the thin black frame - essentially enabling you to blend the plot into the background.
  3. Next on my list is the axis function. MATLAB has the tendency to fit all the data on a plot and disregards scaling by default. In order to correct this, you can issue the axis equal command which sets the aspect ratio so that the data units are the same in every direction. I, personally, have found this useful on many occasions as a plot is no longer distorted.

But then, MATLAB’s plot function only plots what it knows how to plot. So the structure that you created which encapsulates virtually every data type available cannot be plotted by simply typing in plot(myStructure). There are, however, several ways for you to overcome this. You could either rewrite the plot function (not recommended) or simply overload the plot function. Overloading the function will involve some programming on your part, but it can be done.

How you overload it is up to you. I have two methods that overload the plot function. One will operate when only one input is entered (it can be adapted to multiple inputs if necessary) and the other will work with any given number of inputs (basically, a method that uses a sledgehammer to crack a walnut).

My first proposal (my apologies for the formatting by the way - I have yet to find a way to control this): (Edit 02/02/2008: this appears to have only worked the once, so please refer to the second long-winded proposal)

function plot(p)

% Decide if the argument is a structure

if ~isstruct(p)

% Not a structure so run built-in code
disp('Executing built-in code');
builtin('plot',p);

else

% Is a structure so run built-in code
disp(’Executing custom code’);

end

So what’s gone on here, you may ask. Good question. This function is only called when one input is specified (and is called if the file falls into one of the directories added using the addpath method or is in be current directory). Should the first input be of type structure, it runs some custom code (to, perhaps, verify the input data before ripping it apart in order to plot it). If, on the other hand, the input is of some data type that isn’t a structure (e.g. of type double or of type char), then the built-in/hard-wired function is executed using the builtin function.

Should you be feeling particularly adventurous, you could follow proposal two (although this is not recommended as there are definitely better ways in accomplishing this task). So, for novelty value, I have included below the method that uses the sledgehammer to crack one rotten walnut.

My second proposal:

function plot(varargin)

% Criteria for executing custom code

if 3 > length(varargin{1}) && nargin == 1

disp('My own defined function');

if isstruct(varargin{1})

% Run custom code here
% Note: You could still call the plot command here - as long as it
% eventually calls the built-in function

error('Unexpected input: expected a structured object');

end

else

disp(’Running built-in parent function’);

% You may want to cover the structured case below using the
% "isstruct()" function

if isnumeric(varargin{1})

% It appears that numeric data is entered
tempstring = mat2str(varargin{1});

else

% Not numeric
tempstring = ['’ varargin{1} ‘’];

end

for i = 2:length(varargin)

if isnumeric(varargin{i})

% Numeric data entered - put into matrix form
tempstring = [tempstring ', ' mat2str(varargin{i})];

else

% Not a string - just save as text
tempstring = [tempstring ‘, ‘'’ varargin{i} ‘'’ ‘];

end

end

%
% Uncomment for debugging (lets you see the run string):
%[’builtin('’plot'’,’ tempstring ‘)’]

% Render the command using the tempstring as arguments
eval(['builtin(''plot'',' tempstring ')'])

end

The above takes every input possible and, according to your “run my custom code” criteria will run your custom code and take any of the other inputs. In this example, it takes the first input and checks to see if it’s of size 1 (i.e. not multi-dimensional - the code’s bad enough as it is) and that there is only one input. It then moves onto the next step: determining if the first input is a structure. That’s all this function does. I am aware that it probably won’t accept every form of input either - that’s for version 2.
The remainder of the above reforms the original expression (i.e. plot(input1, input2, ..., etc); ) and uses the eval command to execute the builtin command to plot the data. Whilst this is absolutely pointless for most purposes, it merely works as a proof of concept (well, that’s the excuse I’m sticking to) and could be useful for amending the plot function for multiple inputs (particularly where one is unable to know in advance the number of input arguments that will be used).

So, in conclusion, if you wanted to override the built-in plot function, it’s an idea that you know the number of inputs beforehand and then only override that instance of the plot function. Otherwise, your work suddenly becomes all the more complicated… or interesting as I prefer to call it.




Update: 2nd February 2008
After searching for an alternative solution having found the first proposal no longer worked, I found a way to reduce the content of the second version which should also take care of possible problems. The first few lines are the same (i.e. the code that determines whether to execute the custom code which, in this case, is determined by a structured input) but it's the parsing part that has been hugely altered.


And the part you've been waiting for...


function plot(varargin)

% Criteria for executing custom code

if 3 > length(varargin{1}) && nargin == 1

disp('My own defined function');

if isstruct(varargin{1})

% Run custom code here
% Note: You could still call the plot command here - as long as it
% eventually calls the built-in function

error('Unexpected input: expected a structured object');

end

else

disp(’Running built-in parent function’);

builtin('plot', varargin{:})

end


It works as before (using the builtin function to use the original plot function so functionality isn't lost). It's simple and there's no complex parsing or reconstruction of inputs (shame), so I don't know why I didn't think of this in the first instance.


Read more on this article...

MATLAB Licence Management

For those that enjoy altering MATLAB licence files and/or working remotely, this may be of interest to you. Providing you have access to your workplace’s VPN server and that the IT department haven’t locked the network down, you may be able to run MATLAB remotely.

As described by MathWorks, your licence file header may contain a line in the form:

SERVER Licence_Server_Name HostID TCP_PortNumber

When using your (company/institution’s) computer remotely, you are likely going to be on a different domain name regardless of whether you are connected via VPN or not. Consequently, if you are having problems opening MATLAB despite using VPN in the hope it will connect to the licence server, you may wish to check your licence file header before assuming it’s a firewall/network configuration issue.

You can find the licence files (named “license.dat” - take note of the spelling) within your MATLAB directory ($MATLAB).

For Windows installations: $MATLAB\bin\win32\license.dat

For Unix installations: $MATLAB/etc/license.dat

Now, before one starts altering these licence files, consider backing up the original files.

Open the license.dat file within the text editor of your choice and check the form of the header as mentioned above. Should the Licence_Server_Name field not be of the form server.domain.com or server.domain.co.uk but is instead stated as server, this will at least be partly, if not entirely, responsible for the licence issues you are having.

By simply stating the licence server as server, the local computer appends its local domain name and extension (as set by the network configuration) to the server name in the belief that the licence server is connected to your local network. By appending your workplace’s domain and domain extension (i.e. .com, .co.uk, etc.) to the licence server name, the local computer will attempt to connect to the server under your workplace’s domain.

Once you have made changes to your licence file, save it, establish a connection through VPN and then fire up MATLAB. This should solve any issues where two or more networks try to connect to one licence server that is connected to only one of those networks (where each network has a different domain name).

Should this not have solved your problems, it’s possible that the IT department have either used IP filtering (to limit the range in IP addresses that connect to the server) or have invested in a firewall that blocks the port TCP_PortNumber.

So, in a nutshell (and for those that enjoy procedural steps):

  1. Backup your license.dat file
  2. Open your license.dat file in a text editor
  3. Ensure that a domain is indeed specified within the header where the header is in the following form:
    SERVER Licence_Server_Name HostID TCP_PortNumber
  4. If the Licence_Server_Name has a (valid) domain and extension, the problem appears to be caused by a firewall or IP filtering.
    If the Licence_Server_Name doesn’t have a domain and extension, add one (preferably your workplace domain and domain extension) such that the header now reads:
    SERVER Licence_Server_Name.Domain.Ext HostID TCP_PortNumber
  5. Save any changes made
  6. Establish a VPN connection, load MATLAB and await results
  7. If it is either hanging or you have receiving error messages about the licence manager, it’s possible that the domain and domain extension entered is incorrect. Otherwise, the IT department have a firewall or IP filter that’s blocking your licence request.

Another thing to bear in mind is that you should, in theory, keep your VPN connection open whilst you are using MATLAB. By doing so, any other licence requests can be sent to the licence server (such as checking out and checking in toolboxes) when required without causing any further grief. Hence, you should really only disconnect from VPN once MATLAB has closed.

Read more on this article...