Showing posts with label Matlab. Show all posts
Showing posts with label Matlab. Show all posts

Wednesday, December 23, 2015

Matlab Comments in Vim

I'm using vim-commentary but having problems with matlab and octave scripts trying to comment like c blocks

in the vim-commentary documentation it says to do:
autocmd FileType matlab setlocal commentstring=%\%s

but it wasn't working for me.  The solution was to open the matlab.vim file as admin

sudo gedit /usr/share/vim/vim74/ftplugin/matlab.vim

and add

setlocal commentstring=%\%s

to the file

Now it works automatically when vim loads a matlab file!

Saturday, August 16, 2014

Second order Finite Difference Schemes for Non-Uniform Grid Spacing

A lot of credit goes to
http://www.scientificpython.net/

In the attached pdf I lay out the derivation for second order finite differences for non-uniform grid spacing for first and second derivatives.  Higher derivatives can be approximated in a comparable fashion...albeit with a lot more algebra involved in finding the derivatives.

I use Lagrange interpolating polynomials as the base functions and it results in the same derivatives that they provide at http://www.scientificpython.net/pyblog/non-uniform-first-order-finite-differences for the first derivatives.  Second derivatives are the same for the inner points, but they only supply the first order accurate second derivatives at the endpoints.  I wanted a better solution at the ends so I derived it myself.  This derivation contains second order accurate approximations for the endpoints as well.

PDF

Wednesday, July 10, 2013

Arduino Multi-Source Matlab Serial Read

This code is a modified version of the code supplied to me by John Brooks - currently also at Gloyer-Taylor Laboratories - for reading in thermocouple data into Matlab for data manipulation.  Matlab can control an Arduino board with the Arduino IO package freely available by Matlab but it's somewhat limited in its overall functionality.  On the other hand, Matlab makes data manipulation much more convenient than doing so on the board itself.

This code continually searches the serial port for new data sent from the board and stores it, plots it, and writes it to a data file.  It can be set up for single or multiple sources sent to the same port.  For instance, I use it to record temperatures for multiple thermocouples.

clc; clear all; close all;
% Finds all previously opened ports and closes/deletes them
delete(instrfindall);

% Specify Outputs
plotrealtime='y';
writetofile='y';
datafolder='Multi_Test';

num_sources=3;

if strcmp(writetofile,'y')
    date_time=clock;
    outputfilename = [num2str(date_time(1)),'-',num2str(date_time(2)),'-',...
        num2str(date_time(3)),' ',num2str(date_time(4)),'-',...
        num2str(date_time(5)),'-',num2str(date_time(6))];
    if exist(datafolder,'dir')==0
        mkdir(datafolder)
    end
end

%% open port.
% creates and opens new serial port
s = serial ('COM3');
fopen(s);


%% initialize variables
tab=char(9);
I=1;
%data=zeros(1000,3);

%% clears buffer
while(s.BytesAvailable > 0)
    fscanf(s);
end

%% start timer
tic;

%% main function
K=1;
while(true)
%     pause(1)
    %% check to see if data is available at the port
    if s.BytesAvailable > 0
        %% read data and record time
        data=str2double(fscanf(s));
        if isempty(data)
            break;
        else
         
            time=toc;

        end      
        %% adds an additional 1000 points to data and time
       % if rem(I,1000)==0
           % data=cat(1,data,zeros(1000,2+num_sources));
      %  end
     
        %% plots results
        if strcmp(plotrealtime,'y')
            colors1 = '-k.-b.-g.-r.-m.-c.-k.-b.-g.-r.-m.-c.-k.-b.-g.-r.-m.-c.-k.-b.-g.-r.-m.-c.';
            plot(time,data,colors1(K*3-2:K*3),'MarkerSize',10);hold on;
            xlabel('Time (seconds)')
            ylabel('Data')
            drawnow
        end
     
        %% display results to command window
        disp([I,time,data])
     
        if strcmp(writetofile,'y')
            dlmwrite([datafolder,'\',outputfilename,'_',num2str(K),'.dat'],[I,time,data],'-append','newline','pc','delimiter','\t')
        end

        %% iterate counter
%         data(I+1,:)=data(I,:);
        I=I+1;
        K=K+1;

        if K>num_sources
            K=1;
        end
    end
end

%% close port
%fclose(s)


and the arduino code

/***************************************************
 * This is an example for the Adafruit Thermocouple Sensor w/MAX31855K
 *
 * Designed specifically to work with the Adafruit Thermocouple Sensor
 * ----> https://www.adafruit.com/products/269
 *
 * These displays use SPI to communicate, 3 pins are required to
 * interface
 * Adafruit invests time and resources providing this open source code,
 * please support Adafruit and open-source hardware by purchasing
 * products from Adafruit!
 *
 * Written by Limor Fried/Ladyada for Adafruit Industries.
 * BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_MAX31855.h"



void setup() {
  Serial.begin(9600);

  //Serial.println("MAX31855 test");
  // wait for MAX chip to stabilize
  delay(500);
}

void loop() {
  // basic readout test, just print the current temp
  //Serial.print("Internal Temp = ");
  //Serial.println(thermocouple.readInternal());

  //int thermoDO = 8;
  //int thermoCS = 2;
  //int thermoCLK = 3;

  find_temp(0,2,3);


  find_temp(4,5,6);

  find_temp(8,9,10);
delay(1000);
}

void find_temp(int thermoDO,int thermoCS,int thermoCLK){
  Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);

  double C = thermocouple.readCelsius();
  double F = thermocouple.readFarenheit();
  if (isnan(C)) {
    Serial.println("Something wrong with thermocouple!");
  }
  else {
    //Serial.print("C = ");
    Serial.println(C);
    //Serial.println(F);
  }
  //Serial.print("F = ");
  //Serial.println(thermocouple.readFarenheit());
  //delay(1000);

}

Thursday, March 14, 2013

Apparent Matlab R2012a Bug with 'clear' statement

So I found a problem with Matlab R2012a x64...

My problem (not really important):
I'm looking for a string inside a cell array using strfind.  This gives me a cell array with empty cells except where it finds the string.  Then i do a search for isempty in a loop until I find the one that contains a value and I save the index and break the loop.  Then I have a conditional to write data associate with that index.  This repeats for several strings so I clear the index after each completed set of operations.  Example:


% -------------------------------------------------------------------------
% Pressure
% -------------------------------------------------------------------------
    A=strfind(myData.textdata,'Pressure');

    for I=1:length(A)
        AA=isempty(A{I});
        if AA==0
            II=I-1;
            break;
        end
    end
 
    if J==1
        Mean_Pressure=reshape(myData.data(:,II),Nx,Ny);
    else
        Mean_Pressure(end+1:end+Nx,:)=reshape(myData.data(:,II),Nx,Ny);
    end
 
    clear II

Apparent Matlab Problem:  if the 'clear II' statement is exactly one line below the 'end' the variable never clears.

Solution:  There must be a blank line between the 'end' and the 'clear'.

Friday, January 13, 2012

Generating Publication Quality Figures in Matlab


Updated* See Step 7 - Post Processing

Matlab is wonderful for visualizing solutions quickly for the purposes of debugging or exploring numerical solutions. It is pretty bad at figure formatting though. In fact, I don't feel comfortable putting Matlab figures directly into documents because they look so unprofessional. Matlab does have the workspace toolbox thing, but that's not the best. Mostly because the export is exactly the same size as the figure on the screen and setting that size is really inconvenient so axis of adjacent figures don't usually line up well.

This is how I do it:
First we are assuming either the correct sizing for a figure that will fit on half a page so that 2 can be side by side on a 6.25 (or 6.5) inch text width OR that I have one elongated figure that fills the whole width - like a contour plot.

1) Specify the dimensions

% For Normal Figures
height=1.0/1.618; % width/golden ratio
width=1;

% For Wide Figures
% height=1.0/1.618; % width/golden ratio
% width=2;

scale=300; % 3.13 inches

I choose the golden ratio because it's considered aesthetically pleasing to the eye. It works well for large figures, but it might not be perfect for small figures. Just remember if you want to scale from a known dimension in inches use a converter to convert to pixels. 300 pixels is 3.13 inches

You can also position the figure on the screen
xpos=50;
ypos=500;

2) Define the function to be plotted. For the example, I generate one on the spot but this could be an import function
x=0:.01:2*pi;
f1=cos(x);
f2=sin(x);

3) Generate the figure. This doesn't just mean plot the data. The figure is comprised of the figure dimensions, the plot area, the bounding box, etc.. We also want to set the fonts and position

figure; % Create Figure
axes('FontName','Times New Roman') % Set axis font style
box('on'); % Define box around whole figure
set(gcf,'Position',[xpos ypos scale*width scale*height]) % Set figure format

4) Plot the data

hold on
plot1=plot(x,f1,'Color',[1 0 0]);
plot2=plot(x,f2,'Color',[0 0 1]);

by plotting each function as a different plot command and defining plot1 and plot2, we have unique control over the format of each data set.

5) Set Plot properties. This is different than setting figure properties and refers to the data set format

set(plot1,'LineWidth',1,'LineStyle','-');
set(plot2,'LineWidth',1,'LineStyle','--');

% Set Axis Limits
xlim([min(x), max(x)])
ylim([min(f1), max(f1)])

% Create xlabel
xlabel('\xi','FontSize',11,'FontName','Times New Roman','FontAngle','italic');

% Create ylabel
ylabel('\eta','FontSize',11,'FontName','Times New Roman','FontAngle','italic','rot',0);

% Create Legend
hleg1 = legend('$\cos(x)$','$\sin(x)$');

% Set Legend Properties
set(hleg1,'Interpreter','latex')
set(hleg1,'Location','SouthWest')
set(hleg1,'box','on')

There are more properties that can be set, but i just took the ones I use most.

6) Export figure
fig = gcf;
style = hgexport('factorystyle');
style.Bounds = 'loose';
hgexport(fig,'Example_Figure.eps',style,'applystyle', true);
drawnow;

print -depsc2 -tiff myfile.eps

There is something weird here: i don't think i have to use both the hgexport (like clicking File-Save As) and print but I don't get the right format without using both.

7) Post processing. This is really unfortunate. The problem is that Matlab doesn't embed fonts in eps files correctly (or at all). There are functions such as export_fig and exportfig that claim to do this, but I've not had any luck. Part of it is that I don't have time to mess with all the settings and syntax that comes with using other packages. Part of it is my frustration with the whole nonsense.

An option many people seem to use is Adobe Illustrator. The process goes: Open the eps and convert the text to outlines. I think this replaces the text with lines and fills so that the letters appear, but aren't actually text anymore. That's a good idea, but I spent some time poking around the trial and couldn't figure out how to set the damn page dimensions so the exported eps was back to its original size. It would always export it with a big white space around it. I think there's something about the clipping box but I don't have time to mess with this garbage. I'm a scientist, not a graphic designer.

Next option: ACD Canvas. Open the eps in canvas and convert to canvas object. Magically (expected), it imports the eps figure with the correct dimensions! Then select all and "convert to path." I'm not completely sure what goes on behind the scenes with this operation, but it appears to take whatever is selected and lump it all into some kind of vector graphic. Again, the text is no longer dependent on a font. The problem with this is that there is no more editing so make sure it's what you want before you convert it. This works fine and produces nice figures.

UPDATE - Canvas costs money beyond the trial version. Boo. Inkscape is the solution! It's a free, open source program that will do this stuff MUCH easier than Adobe and even easier as Canvas. Open the eps file. Make sure the fonts imported correctly. If not, fix them! Then save as eps. The dialog box will offer some really cool stuff for latex but we don't need that right now. Make sure the box "Convert texts to paths" is selected and the "export area is drawing" is selected (I don't know about the "export area is page" that sounds counter to the previous box but I left mine checked). I don't know what the rest does so leave it or not. It doesn't seem to matter. The important part is that the text is converted to paths!

Beyond that, Inkscape (and the others) let you edit figures. For instance, Matlab will automatically adjust the position of the axis and labels depending on the number of digits in the label. That means the axis won't necessarily line up correctly in the document. Inkscape can adjust the axis dimensions and the location of the labels and titles so that they all look correctly! Awesome!

This isn't perfect but it works pretty well. If you're without a better option, then this is definitely a viable possibility. Here is the whole matlab code:

%% Figure Generator with Format
% =========================================================================
clear;clc;close all

% =========================================================================
% Specify Dimensions and Position on Screen
% =========================================================================
% -------------------------------------------------------------------------
% Figure Dimensions
% -------------------------------------------------------------------------

% For Normal Figures
height=1.0/1.618; % width/golden ratio
width=1;

% For Wide Figures
% height=1.0/1.618; % width/golden ratio
% width=2;

scale=300; % 3.13 inches
% -------------------------------------------------------------------------
% Figure Position on Screen
% -------------------------------------------------------------------------
xpos=50;
ypos=500;

% =========================================================================
% Define Functions to be Plotted
% =========================================================================
x=0:.01:2*pi;
f1=cos(x);
f2=sin(x);

% =========================================================================
% Generate Figure
% =========================================================================
% -------------------------------------------------------------------------
% Figure Properties
% -------------------------------------------------------------------------
figure; % Create Figure
axes('FontName','Times New Roman') % Set axis font style
box('on'); % Define box around whole figure
set(gcf,'Position',[xpos ypos scale*width scale*height]) % Set figure format

% -------------------------------------------------------------------------
% Plot Data
% -------------------------------------------------------------------------
hold on
plot1=plot(x,f1,'Color',[1 0 0]);
plot2=plot(x,f2,'Color',[0 0 1]);

% -------------------------------------------------------------------------
% Plot Properties
% -------------------------------------------------------------------------
set(plot1,'LineWidth',1,'LineStyle','-');
set(plot2,'LineWidth',1,'LineStyle','--');

% Set Axis Limits
xlim([min(x), max(x)])
ylim([min(f1), max(f1)])

% Create xlabel
xlabel('\xi','FontSize',11,'FontName','Times New Roman','FontAngle','italic');
% xlabel('$\xi$','FontSize',11,'FontName','Times New Roman','interpreter','LaTex','rot',0);

% Create ylabel
ylabel('\eta','FontSize',11,'FontName','Times New Roman','FontAngle','italic','rot',0);
% ylabel('$\eta$','FontSize',11,'FontName','Times New Roman','interpreter','LaTex','rot',0);

% Create Legend
hleg1 = legend('$\cos(x)$','$\sin(x)$');

% Set Legend Properties
set(hleg1,'Interpreter','latex')
set(hleg1,'Location','SouthWest')
set(hleg1,'box','on')

% =========================================================================
% Export Figure
% =========================================================================
fig = gcf;
style = hgexport('factorystyle');
style.Bounds = 'loose';
hgexport(fig,'Example_Figure.eps',style,'applystyle', true);
drawnow;

print -depsc2 -tiff myfile.eps