Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Monday, May 24, 2010

MATLAB & C++: Car Talk 1016 Puzzler

Car Talk is a weekly call-in radio show about cars and car repairs on National Public Radio. The hosts, Tom and Ray Magliozzi, are extremely funny and very knowledgeable about the subject. I tend to listen to the show by downloading the podcasts of ‘classic’ episodes (which means ‘old’, ‘previously aired’!)

Among other things the two brothers discuss is the weekly puzzler. That is, every week they hold a contest with a puzzle (brain-teaser) with the winners announced during the following episode (a week later.)

The puzzler on April 19th (I am a few episodes behind) is called Stevie and his Moto and in brief, it asked listeners to find (the) two temperatures in Fahrenheit and Celsius that have the digits ‘exactly reversed.’

For example, [one of the big signs that display the time and temperature] might have read 31 degrees Fahrenheit, and when it showed the centigrade reading it said "13."

Though the contest is now about a month old I decided to spend a few minutes to code a solution in MATLAB and then for kicks re-coded the solution in C++.

MATLAB

The algorithm is straight forward:

  1. Define array of values for temperature in degrees Fahrenheit – no decimals.
  2. Calculate equivalent temperature in degrees Celsius – rounded towards the nearest integer.
  3. Compare 1st digit of degrees F with 2nd digit of degrees C AND 2nd digit of degrees F with 1st digit of degrees C.
  4. If-and-only-if BOTH are equal then we have a match.

For this algorithm to work the range of Fahrenheit values needs to be restricted to the ones that would result in positive Celsius values that also have two digits (which was set as a requirement when the puzzler was explained.) If the range is not restricted then there would be a match for 40F and 4C. And since I like to play around with ideas I added on more test to make sure that the algorithm is more correct: count the digits of the integer.

For integers a quick solution is to count the number of digits for both degrees F and C and compare. For positive non-zero numbers we can use:

>> floor( log10( number) ) + 1;

This works because for positive non-zero numbers the base-10 logarithm provides the exponent of the base that would result in the number. That is:

x = 10^y then y = log10(x)

E.g.

1000 = 10^3 then log10(1000) = 3

Therefore, if the exponent is known the number of digits if the number can be calculated.

The snapshots of the code and output are shown below:

cartalk mfile

cartalk mfile out

C++

The idea is exactly the same. The only difference is that I had to code my own rounding function which is straight forward (even for me!)

 cartalk c   01

The rounding function might not very elegant but works!

cartalk c   02

The output is shown below.

cartalk c   03

Thursday, April 15, 2010

MATLAB: Generate Carousel I

In earlier posts I described how to generate a rotating cylinder using MATLAB and how to define to coloring scheme of the rotating cylinder. The reason for these exercises was that I wanted to write code that would create a carousel for entertainment and because I can. I selected MATLAB because among other great attributes it is perfect for prototyping.

I am not done with the design yet but so far it consists of 3 elements: Cylinder, cone, and circle. The cylinder was described in the aforementioned posts. For the other two elements:

CONE:

The roof of the carousel is a cone described using the following parametric equations:

x = (h-u)/hrcostheta

y = (h-u)/hrsintheta

z = u

where, h is the height of the cone, r is the radius of the base,  u in [0,h] and theta in [0,2pi).

In the MATLAB codespace the following entry was used to describe a cone:

rCc = 15; %radius
thetaCc = linspace(0, 2*pi, N);
hCc = linspace(4, 7, M); %height

[UCc, hCc_] = meshgrid(thetaCc,hCc);

[XCc,YCc,ZCc] = gkcone(rCc,hCc_,UCc);

hhCc = surf(XCc,YCc,ZCc);
set(hhCc,'CData',colorCylinder);

=============================================================

function [x,y,z] = gkcone(radius,height,theta)

step = (max(max(height)) - height) ./max(max(height));

x = step .*radius .*cos( theta );
y = step .*radius .*sin( theta );
z = height;

CIRCLE:

Parametric equations were used to describe the circle too. The equations are the same as the cylinder but with a zero z-axis component.

I created 4 cylinders, 4 circles, and a cone with the following result:

The color scheme of the circles is solid white or solid gray. These where generated using:

color_ = ones(M,N+1,3); % WHITE

color_ = ones(M,N+1,3) * 0.9; % GRAY

Tuesday, March 9, 2010

MATLAB: Generate Rotating Cylinder II

In an earlier cylinder post I put together MATLAB code that could generate a rotating cylinder. The cylinder was described using parametric equations

x = rcostheta 

y = rsintheta

z = z

for z in [0,h] and theta in [0,2pi).

The coloring scheme of the rotating cylinder was defined with indexed values which is a quick way to do it but not very intuitive especially if you are used to RGB (Red-Green-Blue) definitions.

MATLAB makes it easy to specify truecolor that can be used to define the vertex colors (through the CData property) by simply defining an m-by-n-by-3 array, where the 3 corresponds to the RGB triplet. That is, the first m-by-n matrix contains the red components, the second the green components, and the third the blue components of the colors.

For my project I selected an alternating white, light blue, and pink.

The code:

% per MATLAB: white: [1 1 1]
% per MATLAB: light blue: [0.043    0.518    0.780]
% per MATLAB: pink: [1.000    0.600    0.784]

colorIndex = [
   1 1 1;
   0.043    0.518    0.780;
   1.000    0.600    0.784;
   ];

coloring = ones(M,N+1,3); % All white

for id = 2:3:N+1
   for jd = 1:3;
      coloring(:,id,jd) = coloring(:,id,jd) *colorIndex(2,jd);
   end
end

for id = 3:3:N+1
   for jd = 1:3;
      coloring(:,id,jd) = coloring(:,id,jd) *colorIndex(3,jd);
   end
end

First the truecolor scheme parameter coloring is set to white for all values in the m-by-n-by-3 array. The reasons are:

  1. I elected a third of the multi-dimensional array to be white.
  2. Speed up the 2 for-loops.

The for-loops are a quick way to define the other two colors per column for the rest of the array. The rest of the code is the same as shown in the earlier post.

The results is:

 

truecolor_flat

 

 

shading flat

 

 

 

truecolor_interp

 

 

shading interp

Tuesday, March 2, 2010

MATLAB: Generate Rotating Cylinder

I wanted to play with this as a building block for a bigger project.  (These projects keep me entertained!)

I wanted to write a bit of MATLAB code that would create a colorful rotating cylinder. I know that core MATLAB offers the function cylinder that can generate surfaces of revolution (and thus cylinders!) However, I do not particularly like to be spoon-fed code all the time. Especially when it is straight forward to use a bit of math and code a few extra lines.

Here it goes:

% Define number of points on the x and z axis
N = 64;
M = 32;

% Create points along the x and z axis

x = linspace(-pi, pi, N);
z = linspace(-2, 2, M);

% Create color assignment for each data point.
% Cdata is a property of function surf that defines the vertex colors. A
% matrix containing values that specify the color at every point in ZData.

% Use pseudo-random number generator for ‘unique’ pattern’. Define outside loop to maintain assignment of colors for all iterations.

coloring = rand(M,N+1);

% Code in for-loop to generate rotational motion.

for ii = 1:N
   dummy = [ii:N 1:ii];
   x_ = x(dummy);
   [xx, zz] = meshgrid(x_,z);


   % Use parametric equations
   X = 1 .*cos(xx);
   Y = 1 .*sin(xx);
   Z = zz;


   h = surf(X,Y,Z); % Create 3D surface plot

   axis off
   set(h,'CData',coloring) % Use color scheme defined outside of loop
   shading interp


   F(ii) = getframe; % Get movie frames


   pause(0.1) % To observe motion
end

An AVI movie can be created by playing the movie frames stored in memory:

movie2avi(F, 'rotatingCylinder01.avi', 'fps', 10, 'compression', 'Cinepak')

Random coloring schemes with stripes can be created as follows:

coloring = rand(M,N+1)

scheme01

c = rand(1,N+1);
coloring = repmat(c, [M 1]);

scheme02

c = rand(M,1);
coloring = repmat(c, 1, N+1);

scheme03

Monday, January 25, 2010

GDP per Capita versus FIFA Rank

Another typical excuse offered to justify the ability of some countries to win consistently is their economic output. It makes sense to some extent. The richer countries have more money to invest in sports and high tech training facilities. The citizens of the rich countries have a higher standard of living and tend to expose their children to sports at an early age. Rich countries have established leagues and actively participate in international sports associations and sporting events.

But is that really the case? It is well established that money buy superb talent and thus success at the club level. (E.g. exhibit A: Chelsea FC; Exhibit B: Real Madrid C.F.; Exhibit C: F.C. Internazionale; etc.) But does money create football talent that can compete at  a national level? Again it is possible, but is it likely?

In other words: Is it really the economy, stupid?

It easy to compare FIFA Rank with GDP per capita found in the CIA factbook. GDP is the Gross Domestic Product which is the value of all goods and services made within a country. The GDP per capita is GDP divided by population and a better metric that shows how well off the citizens of the country are. Also helps dealing with England. The plot of the data versus the 12/2009 FIFA Rank is shown below.

FIFARankvsGDPCapita

It was more fun generating that plot! The MATLAB code to generate the plot is shown below:

plot( points, GDPcapita*1e-3, 'o', 'markersize', 5, ...
  'markerfaceColor', [0 0.8 0], 'markerEdgeColor', [0 0.2 0.7])

P = polyfit(points, GDPcapita, 1);

vv = polyval(P,points);

residualSTD = std( vv - GDPcapita);

R = corrcoef(points, GDPcapita);

hold on
plot(points, vv *1e-3, 'k-', 'linewidth', 1.5)
hold
off
grid on

axis([200 1800 1 ceil(max( GDPcapita*1e-3 )) ])
set(gca, 'XTick', [200:200:1800], ...
   'YTick', [1:4:ceil(max( GDPcapita*1e-3 )) ceil(max( GDPcapita*1e-3 ))], ...
   'fontsize', 9, 'fontname', 'Consolas')
xlabel('FIFA Rank Points')
ylabel('GDP per capita in thousands USD')
title('Data (dots) and 1st order fit (line)')

text(points + 30, GDPcapita*1e-3, strrep(country, '_', ' '), ...
   'fontname', 'consolas', 'fontsize', 10, 'color', 'b')

MATLAB also offers a built-in GUI (plottools) that can do a lot of great things with mouse-clicks. My preference is to use command line interfaces. (The good thing about GUIs is that What You See Is What You Get. The bad thing about GUIs is that What You See Is The Only Thing You Get!) Actually, that particular GUI is good in that it does not seem to leave anything out and some times I use it because it is faster than writing code for an unusual aspect of an one off plot.

Back to the plot: There is a general trend that says rich countries field good football teams. But the correlation is very weak. Also, the data seems shifted above and below the trendline which is probably the result of a binomial distribution (rich versus poor.) And Brazil and Argentina that are perennial winners do not have very wealthy citizens. Therefore:

It is not likely that national economic output and thus national wealth is a significant factor in the success of a country’s national team in world football!

Basic statistics for the 32 countries participating in the 2010WC:

Sample size = 32

Max: $47,500 (USA)

Min: $1,500 (Ghana)

(GDP per capita for Greece: $32,100)

Mean: $21,391

Median: $22,100

Intercept: 8,362.5

Slope: 14.1

Residual std. deviation: $13,978

Correlation = 0.2772

Friday, January 15, 2010

MATLAB: Read formatted input file

The data collected from the FIFA Ranking table and the CIA Factbook were entered in a 32-row by 8-column tab delimited text file shown below.

WCTextFileCapture_

Obviously, it can be easily manipulated with Excel but I also want to do some more work that is easier to do with MATLAB.

It is straight forward to open the file with Excel, copy a column, and cut and paste as input to variable in the command window or a file. But that is too crude for my taste and it does not work for very large files. Plus MATLAB (7.1 R14) offers a number of functions that can read formatted data. These functions are outlined below. For each case I get an estimate of runtime performance by measuring elapsed time using tic-toc. Prior to running each case I clear the memory using clear all as shown in Case 1.

Case 1: use IMPORTDATA
Function importdata will read the text file and assign the data in parameters data and text to textdata. Works OK but not perfect because it can easily confuse data and text.

clear all

tic

M = importdata('WC2010_GK Stats.txt');

fifaRank = str2num( char(M.textdata(:,1)) );
country = M.textdata(:,2);
points = M.data(:,1);
GDPcapita = M.data(:,3);

toc

Case 2: use STRREAD
Function can read formatted data from a string. It requires a loop to go through the file and string manipulation. However, it is pretty fast and reliable. 

fid = fopen('WC2010_GK Stats.txt', 'r');

n = 1;

% If fgetl encounters EOF indicator, it returns -1
while 1
   tline = fgetl(fid); % return the next line of the file associated w/ fid
   if ~ischar(tline),   break,   end % terminate loop
   dummy = strread(tline, '%s');
   % Preallocate to speed up though in this case not much difference
   fifaRank(n) = str2num( char( dummy(1,:) ) );
   % NOTE: theoretically str2double is faster than str2num but I have never
   % seen any real advantage!

   country(n,:) = dummy(2,:);
   points(n) = str2num( char( dummy(3,:) ) );
   GDPcapita(n) = str2num( char( dummy(5,:) ) );
   n = n + 1;
end

fclose(fid);

 

Case 3: use TEXTREAD
Function can read formatted data form text file. It easy to use once you read the (extensive) documentation. 

[fifaRank, country, points, x, GDPcapita, y, z, w] = ...
   textread('WC2010_GK Stats.txt', '%d %s %f %f %f %f %f %f');

 

Case 4: use SSCANF
Function sscanf reads data from the MATLAB string s, converts it according to the specified format string, and returns it in matrix A in column format. For a mixed number + character string the function returns all numbers which can be painful!!

fid = fopen('WC2010_GK Stats.txt', 'r');

n = 1;

% If fgetl encounters EOF indicator, it returns -1
while 1
   tline = fgetl(fid);
%return the next line of the file associated w/ fid
   if ~ischar(tline),   break,   end
  
% Read in the numerical values; Use * to ignore character input for
   % first pass. The reason is that countrly name is variable length.
   % Recall that conversion characters marked with asterisk are NOT
   % returned.

   A = sscanf(tline, '%e %*s %e %e %e %e %e %e', Inf);
   fifaRank(n) = A(1);
   points(n) = A(2);
   GDPcapita(n) = A(4);
  
% Now do a second pass with sscanf ignoring numerical characters.
   % Then use char to put name together.
   B = sscanf(tline, '%*e %s %*e %*e %*e %*e %*e %*e', inf);
   country(n,:) = cellstr( char(B) );

   n = n + 1;
end

fclose(fid);

 

Case 5: use FSCANF
Function fscanf is good about handling numerical data and is pretty fast but it does not handle character data very gracefully. I would need to write additional code to format the character data properly.

fid = fopen('WC2010_GK Stats.txt', 'r');

[A, count] = fscanf(fid, '%e %*s %e %e %e %e %e %e', [7 32]);

fifaRank = A(1,:);
points = A(2,:);
GDPcapita = A(4,:);

% Need to set the file position indicator to the beginning of the file
frewind(fid)

% and use fscanf a second time
B = fscanf(fid, '%*e %s %*e %*e %*e %*e %*e %*e');

fclose(fid);

Case 6: use TEXTSCAN
Function textscan is a fairly new function intended to replace textread and strread. Function textscan reads in the data, formats them according to format specifiers, and place them in cells in a cell array.

fid = fopen('WC2010_GK Stats.txt', 'r');

A = textscan(fid, '%d %s %f %f %f %f %f %f'); % data are placed in cell array

fifaRank = A{:,1};
country = A{:,2};
points = A{:,3};
GDPcapita = A{:,5};

fclose(fid);

I mentioned earlier that I quantified the performance of each case on an AMD X2 Dual Core Processor 3800+ with 3 GB of RAM. Average runtime results for my small file are tabulated below.

 

Case Function Elapsed time [sec] Comments
1 importdata 0.2177

41x slower. Standard import data function. Need to check data parameters.

2 strread 0.0352

6.6x slower. Pretty reliable.

3 textread 0.0222

4.2x slower. Least code.

4 sscanf 0.0175

3.3x slower. Needs a bit of code and care with text data. Possibly the function I have used the most.

5 fscanf 0.0104

2x slower. Text not properly displayed. More code needed. Very good for numerical data.

6 textscan 0.0053

Fastest! Efficient! Backwards compatibility issue…

Wednesday, December 23, 2009

MATLAB gem II: An example

While I was ‘playing’ with the function fdep I decided to write a small M-file to show usage and potential problem.

The code does not produce any useful results but it is not junk either. It calls functions from a few toolboxes. Each function uniquely appears in each toolbox; No ambiguity. Then there is a parameter whose name shadows the name of a MATLAB function.

%% Quick code to test fdep

clear all

% Create 0-mean normal distribution with std = 2
Y = 0 + 2.* randn(1,128);

n = length(Y); % Length of vector n

yy = ceil( max( abs(Y) ) ); % max abs value of data

%% Run sequence plot - MATLAB

subplot(221)
plot(Y, '-')
grid on
axis([1 Inf -yy yy])
title('Run Sequence plot')

%% decimate - Signal Processing Toolbox

YY = decimate(Y,2);

subplot(222)
plot(linspace(1,128,length(YY)), YY, '-')
grid on
axis([1 Inf -yy yy])
title('Decimated Run Sequence plot')

%% Create histogram - MATLAB + Statistics Toolbox

subplot(223)
hist(Y)
hold on
histfit(Y)
hold off
axis([-yy yy 0 Inf])
title('Histogram')

%% Normal probability plot - Statistics Toolbox

subplot(224)
normplot(Y)
title('Normal Probability Plot')

%% Unrelated code: Use parameter named 'step' – MATLAB

lamda = 100;

K = 154;

step = 0;
count = 0;

for id = 1:K+1
   dummy = exp(-lamda) *lamda^(id-1) /factorial(id-1);
   step = step + dummy;
   count = count + 1;
end

The code results in the following plot:

testCode_0912_01

The code is actually 3/4 useful but that is another story.

Now, if you execute fdep from the command line on the M-file shown above the output would look like:

>> P = fdep('testCode_0912_01');
ROOT   : > D:/Documents and Settings/../My Documents/MATLAB/Testing Ground/testCode_0912_01.m
1    1   : | testCode_0912_01      S  0:

-------------  NO USER-DEFINED DEPENDENCIES FOUND
M-FILE       : D:/Documents and Settings/../My Documents/MATLAB/Testing Ground/testCode_0912_01.m
P-FILE       :                                                                                       
MODULE  #   1: testCode_0912_01                                                                      
type         : SCRIPT                                                                                
created      : 23-Dec-2009 12:30:36                                                                  
size         : 1046 bytes                                                                            
lines        : 62                                                                                    
comments     : 9                                                                                     
empty        : 21                                                                                    
recursive    : no                                                                                    
f/eval..     : not used                                                                              
unresolved   : no                                                                                    
calls    TO  :     0  user defined                                                                   
called   FROM:     0  user defined                                                                   
calls in FILE:    20                                                                                 
subfunctions :     0  inside  file                                                                   
nested       :     0                                                                                 
anonymous    :     0                                                                                 
f/eval..     :     0                                                                                 
unresolved   :     0                                                                                 
ML      stock:    13                                                                                 
ML  built-ins:    10                                                                                 
ML    classes:     1                                                                                 
OTHER classes:     0                                                                                 
ML  toolboxes:     4                                                                                 
             :    +1  Control System Toolbox (8.2) [control]                                         
             :    +2  MATLAB (7.7) [matlab]                                                          
             :    +3  Signal Processing Toolbox (6.10) [signal]                                      
             :    +4  Statistics Toolbox (7.0) [stats]                                               
>>

>> P.toolbox

ans =

    'Control System Toolbox (8.2) [control]'
    'MATLAB (7.7) [matlab]'
    'Signal Processing Toolbox (6.10) [signal]'
    'Statistics Toolbox (7.0) [stats]'

>>

Mostly correct; Unfortunately it identifies the presence of the Control Systems Toolbox because of the presence of parameter step. Can’t have everything! Still, a very useful function.

 

Technorati Tags: ,,,,,,

Tuesday, December 22, 2009

MATLAB gem II

Recently I had to figure out which MATLAB toolboxes a massive program is using. The program itself is a smorgasbord of over 5000 (!!) function written by a small army of developers over a number of years. It is a form of spaghetti code based on OOP ideals. Seemingly, no start and no end.
Normally I would not care. I would approach the code as a basic developer and write my new code as needed. I know that applying patches is not a good practice (I really dislike the idea) but my time is a lot more valuable than trying to follow calls forever. However, in this case all that code needs to be installed on more machines. And the installation is temporary. Therefore it makes no sense to buy the full-MATLAB-with-all-toolboxes-plus-Simulink-and-everything-else kind of license we typically buy. Therefore, I had to figure out what exactly that particular program is using.
So I Googled the problem and found exactly what I was looking for in the file exchange of MATLAB Central. The function contributed by us; The contribution is titled fdep: a pedestrian function dependencies finder and it is exactly what I was looking for.
The function (set of functions really) is well written and documented. It very quickly goes through a MATLAB program and displays information about users defined functions, sub-functions, MATLAB functions, toolboxes, calls, etc. Toolboxes!! There is a command line interface and a graphical one. It even comes with an HTML help file. Great work!
One caveat: At least when it comes to the toolboxes the result could be inaccurate. The reason for that is that if a developer is using a parameter name that shadows the name of an existing MATLAB function the the conflict is resolved in favor of MATLAB. For example, if a developer programmed the statement
step = 1;

then fdep will determine that step is the MATLAB function from the Control System Toolbox. That is a problem with namespace littering. And with all the toolboxes available for MATLAB pretty soon all normal dictionary words will shadow some MATLAB function. Anyway…
For my case I used the function fdep in a script that navigated through the mess of code and interrogated each function and printed back the toolbox result. The function worked quickly with few hick-ups and returned reasonable results: A few toolboxes in addition to core MATLAB. It might be that a couple of them seem suspicious but the effort required to uncover details is out of scope!
Technorati Tags: ,,,,

Monday, June 1, 2009

MATLAB: Favorite Shortcuts

Some of my favorite (and most used MATLAB shortcuts).

Description Callback
Open folder XX winOpen ‘C:\XX\’
Change directory to folder XX cd ‘C:\XX\’
Open Help Browser helpbrowser
Close Help Browser com.mathworks.mde.desk.MLDesktop.getInstance.closeHelpBrowser
Clear Workspace

clear all

close all

clc

Set Editor at specific state
(See also here and here)

editorServices = com.mathworks.mlservices.MLEditorServices;

load('C:\MATLAB\Editor State Files\xxxxAnalysis.mat')

for id = 1:length( editorState )
      editorServices.openDocument( editorState(id) )
      end

Sunday, May 31, 2009

MATLAB: Shortcut Editor State

In an earlier blog entry I documented a way to preserve that state of the editor (that is all windows open in the editor) in a .mat file that can be reloaded whenever needed.

I decided to make a shortcut of the most frequently re-loaded set of windows. It is easy to do in MATLAB:

  • Highlight code of interest.
  • Drag to shortcut toolbar.
  • Enter ‘Label’
  • Done!

For my case I added the shortcut to a personal folder accessible from the Start button (Start – Shortcuts).

shortcuts_organizer_

The code entered in the Callback field:

editorServices = com.mathworks.mlservices.MLEditorServices;

load('C:\Documents and Settings\User\My Documents\MATLAB\Editor State Files\xxxxAnalysis.mat')

for id = 1:length( editorState )
      editorServices.openDocument( editorState(id) )
      end

GRIPE ON:

What is the point of having a personal folder accessible from the Start button??

I am using it as a repository of commands that would be good to have close but not necessarily add to toolbar (and thus add to clatter). However, they do not count as ‘shortcuts’. A shortcut is an 1-2 clicks operation not something that essentially takes 3-4 clicks to launch. That counts as a sub-sub-… menu! Not to mention ‘out of sight out of mind’.

It would have been much better if by making a personal shortcut folder you actually place it as an icon to the toolbar that can be launched via a 2-click operation. And everything is right there in front of you so you do not forget your shortcuts. And everything is organized.

Thursday, May 28, 2009

MATLAB: Spline My Monogram

I saw that exercise as an assignment for a MATLAB course and it reminded me of my senior year in college studying aerospace engineering. As a senior project me and 3 other people designed and build and aeroplane (great fun!) and among other things I used a plastic spline and some weights called ‘ducks’ (to set the curvature). Much easier to do generate splines with a computer!

The code to generate cubic splines is well known and makes use of a tridiagonal system of matrices which lends itself well to MATLAB programming. However, the MATLAB people have made available standard spline functions (also exotic versions for a friendly fee!) which makes the whole operation pretty straight forward. See below; All code is entered in the MATLAB command window.

I first wrote my monogram on an 8x10 engineering paper and determined the (x, y) coordinate pairs (my ducks!) See plot below for my data set. (Set axis to equal for proper appearance.)

>> M = load('monogram data.txt');

>> x = M(:,1);
>> y = M(:,2);

>> plot(x, y, 'o', 'markersize', 5)
>> grid on
>> axis equal

step1_data

If the MATLAB Spline toolbox is available then the function SPCRV will work well.

>> values = spcrv(M,2); % 2nd order

>> subplot(121)
>> plot(x, y, '.b', values(:,1), values(:,2), '-r', 'linewidth', 1)
>> grid on
>> axis equal

>> subplot(122)
>> plot(values(:,1), values(:,2), '-r', 'linewidth', 1)
>> axis equal

step2_spcrv

It is almost as easy to generate the spline using the standard 3rd order SPLINE function available with basic MATLAB. I need to define common parameter t so x(t) and y(t) can be found.

>> n = size(M,1); % number of data points

>> t = 1:n;

>> ts = 1:1:n;

>> xs = spline(t,x,ts);
>> ys = spline(t,y,ts);

>> subplot(121)
>> plot(x, y, '.b', xs, ys, '-g', 'linewidth', 1)
>> grid on
>> axis equal

>> subplot(122)
>> plot(xs, ys, '-g', 'linewidth', 1)
>> axis equal

step3_spline

Compare the two solutions (spcrv vs. spline); The two curves are identical.

step4_compare

Reduce the step size of parameter ts to improve appearance of my monogram.

ts = 1:1/20:n;

xs_ = spline(t,x,ts);
ys_ = spline(t,y,ts);

subplot(121)
plot(x, y, '.b', xs_, ys_, '-g', 'linewidth', 1)
grid on
axis equal

subplot(122)
plot(xs_, ys_, '-c', 'linewidth', 1)
axis equal

 

step5_splineFine

Looks pretty nice!

Now I just have to create my own code (as I have done years ago in FORTRAN) and compare with the MATLAB result. Another day maybe!

Thursday, April 16, 2009

MATLAB gem

On March 5, Daniel (I do not know anything else about the person) offered a MATLAB gem as a comment to Loren Shure's MATLAB blog Loren on the Art of MATLAB. In his comment he offered a way to save the state of the editor (i.e. all scripts open in the editor) in a .mat file which can be loaded at a later time and reset the editor with the exact same scripts. Though he suggests caution since it is 'undocumented functionality' I have found that it works well. It is very cool and useful!

Daniel's comment can be found here:


A few words about Loren's blog: It is one of the two The Mathworks blogs that I follow regularly. She is obviously an expert and she offers unique MATLAB insights (my kind of person). Almost every one of her blog entries gives me an opportunity to consider, think, and learn. 

So I used that and wrote my own function:

function setEditorState( filename, option )
%
%
% This is a neat trick that I picked up from Loren's blog offered by a guy
% named Daniel:
%
% http://blogs.mathworks.com/loren/2009/03/03/whats-in-your-startupm/#comment-30128
%
% The function same the state of the editor (all tabs open) to a file which
% can be reloaded and set the editor to the exact same state. Very cool!
%
% Inputs:
%     filename: String in single quotes without extention.
%     option: Strings 'save' or 'load'
%
% Example:
%     >> setEditorState( 'prova', 'save' )
%
% Note:
%     MAT files with the list of open files are always save in:
%
% <'C:\Documents and Settings\User\My Documents\MATLAB\Editor State Files\'>
%
%

% Error check number of input arguments
if (nargin <>
   error('myApp:argChk', 'Wrong number of input arguments')
end

% I want to save all save 'states' in a specific folder.
dirPath = 'C:\Documents and Settings\User\My Documents\MATLAB\Editor State Files\';

% Save editor state
if strcmpi(option, 'save') == 1
   
   editorServices = com.mathworks.mlservices.MLEditorServices;
   
   editorState = editorServices.builtinGetOpenDocumentNames();
   
   save ( [dirPath filename '.mat'], 'editorState', '-mat' );
   
% Load editor state
elseif strcmpi(option, 'load') == 1
   
   editorServices = com.mathworks.mlservices.MLEditorServices;
   
   load( [[dirPath filename '.mat']] )
   
   for id = 1:length( editorState )
      
      editorServices.openDocument( editorState(id) )
      
   end
   
end