Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Wednesday, June 1, 2016

Label 3D Scatter Plots in Python

I work with grid data and sometimes I need to see the sequence in which nodes are ordered.

This can be done with annotate in 2D (see documentation) but not 3D.  Alternatively use "text"

ax.text(x[i], y[i], z[i] , "%s" % (str(i)), size=20, zorder=1, color = "black")

x,y,z are the location in 3-space, %s stores a string, str(i) converts "i" into a string and puts it in place of %s.

Thursday, May 19, 2016

Initiating Multidimensional Vectors in c++

I found this page helpful for 3D since 2D was reasonably straightforward.
http://www.cplusplus.com/forum/articles/7459/

2x1
std::vector array1D(2);

2x3
std::vector > array2D(2,std::vector(3))

2x3x4
std::vector > > array3d;
    int rows = 2, columns = 3, planes = 4;
    array3d.resize(rows);
    for (int i = 0; i < rows; i++) {
     array3d[i].resize(columns);
     for (int j = 0; j < columns; j++) {
        array3d[i][j].resize(planes);
     }
    }

and using structures
struct VoxelProperties {
    // Contains:
    int NumInVoxel; // Num points in each voxel
    std::vector NodeIndex; // Array to store the Index of points in the voxel
};
    
    std::vector Voxels(2);
    Voxels[0].NumInVoxel = 1;
    Voxels[0].NodeIndex.push_back(13);
    std::cout << Voxels[0].NumInVoxel << std::endl;
    std::cout << Voxels[0].NodeIndex[0] << std::endl;

    std::vector > Voxels(2,std::vector(3));
    Voxels[0][0].NumInVoxel = 1;
    Voxels[0][0].NodeIndex.push_back(13);
    Voxels[1][1].NumInVoxel = 11;
    Voxels[1][2].NodeIndex.push_back(15);
    std::cout << Voxels[0][0].NumInVoxel << std::endl;
    std::cout << Voxels[0][0].NodeIndex[0] << std::endl;
    std::cout << Voxels[1][1].NumInVoxel << std::endl;
    std::cout << Voxels[1][2].NodeIndex[0] << std::endl;

    std::vector > > Voxels(2,std::vector(3));
    std::vector > > Voxels(2,std::vector(2) >(3));
    std::vector > > Voxels;
    int rows = 2, columns = 3, planes = 4;
    Voxels.resize(rows);
    for (int i = 0; i < rows; i++) {
        Voxels[i].resize(columns);
    for (int j = 0; j < columns; j++) {
       Voxels[i][j].resize(planes);
    }
    }
    Voxels[0][0][0].NumInVoxel = 1;
    Voxels[0][0][1].NodeIndex.push_back(13);
    Voxels[1][1][2].NumInVoxel = 11;
    Voxels[1][2][2].NodeIndex.push_back(15);
    Voxels[1][2][2].NodeIndex.push_back(16);
    std::cout << Voxels[0][0][0].NumInVoxel << std::endl;
    std::cout << Voxels[0][0][1].NodeIndex[0] << std::endl;
    std::cout << Voxels[1][1][2].NumInVoxel << std::endl;
    std::cout << Voxels[1][2][2].NodeIndex[0] << std::endl;
    std::cout << Voxels[1][2][2].NodeIndex[1] << std::endl;

Friday, April 1, 2016

Min, Max, argMin, argMax of std::vector in c++

I love c++.  I hate c++. I can confirm that c++ exists.  There... that's how I feel.  Coming from basic to VB to Matlab to Fortran to python to c++ - and all within the realm of numerical analysis - I view c++ as that dumb guy who thinks he's so much smarter than everyone else.  The rest of us just have to deal with him because he...is...always...there... but nobody really respects him (Linux: I'm talking to you too even though I have grown quite fond of you as my daily OS).

Anyway...ya ya ya c++ writes operating systems.  Beat that Fortran.  At least if I want to find the minimum and maximum values of an array, it's simple in Matlab and Fortran and Python and ... mrp min(x), max(x), argmin(x), argmax(x) or something simple like that.

Stackexchange is a godsend...not so much for this question though.

Here is how to do it in c++ using c++ BS to do it.

I almost exclusively use std::vectors so that's what I'm talking about now.

double min = *std::min_element(x.begin(), x.end());
double max = *std::max_element(x.begin(), x.end());

int argMin = std::distance(x.begin(), std::min_element(x.begin(), x.end()));
int argMax = std::distance(x.begin(), std::max_element(x.begin(), x.end()));

Tuesday, March 15, 2016

Convert git --bare to normal

I was making a bunch of --bare repos for interpreted codes.  I started working in compiled languages and found it nicer to have the compiled program easily available so my coworkers can just copy and run it rather than cloning and compiling themselves.  I wanted to convert the --bare to normal repos.  Enter stack exchange!

http://stackoverflow.com/questions/10637378/how-do-i-convert-a-bare-git-repository-into-a-normal-one-in-place

I'm reposting here because you have to read the answer and the comments to get it all working.

Make a .git folder in the top-level of your repository.
Move the all the repo folders into the .git folder (HEAD branches config description hooks info objects refs) into the .git you just created.
Run git config --local --bool core.bare false to convert the local git-repository to non-bare (might need sudo)
run git checkout master (this one was found in the comments)

Wednesday, November 4, 2015

My tmux.conf file

I took this from a couple places namely
http://tangledhelix.com/blog/2012/07/16/tmux-and-mouse-mode/
https://unwiredcouch.com/2013/11/15/my-tmux-setup.html
https://wiki.archlinux.org/index.php/Tmux

very helpful


# Change prefix to C-s
unbind C-b
set -g prefix C-s
bind C-s send-prefix

# force a reload of the config file
unbind r
bind r source-file ~/.tmux.conf

# start window numbering at 1 for easier switching
set -g base-index 1

# colors
set -g default-terminal "screen-256color"

# unicode
setw -g utf8 on
set -g status-utf8 on

# status bar config
set -g status-left "#h:[#S]"
set -g status-left-length 50
set -g status-right-length 50
set -g status-right "⚡ #(~/bin/tmux-battery) [✉#(~/bin/imap_check.py)] %H:%M %d-%h-%Y"
setw -g window-status-current-format "|#I:#W|"
set-window-option -g automatic-rename off

# listen to alerts from all windows
set -g bell-action any

# rebind pane tiling
bind V split-window -h
bind H split-window

# quick pane cycling
unbind ^A
bind ^A select-pane -t :.+

# screen like window toggling
bind Tab last-window
bind Escape copy-mode

# vim movement bindings
set-window-option -g mode-keys vi
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

# Enable mouse scrolling
#set-window-option -g mode-mouse on
set -g mode-mouse on
set -g mouse-resize-pane on
set -g mouse-select-pane on
set -g mouse-select-window on

My .vimrc file

I'm certainly no expert in vim or all the packages.  Here's what I have so far

vundle package manager
syntastic for syntax error flags
vim-airline for aesthetic bar and plugin integration
vim-commentary for easy comment/uncomment
vim-gitgutter to identify changes since last commit
YouCompleteMe for autocompletion (no longer bothering with it)

most of these can be installed by :PluginInstall inside vim
YouCompleteMe is a bit more indepth http://christopherpoole.github.io/setting-up-vim-with-YouCompleteMe/

vundle requires .vimrc edits to work

here is my .vimrc file

"""""""""""""""""""""""""""""
" Must Haves
"""""""""""""""""""""""""""""
filetype off

set nocompatible
set modelines=0
"""""""""""""""""""""""""""""
" Vundle
"""""""""""""""""""""""""""""
" set the runtime path to include vundle and initialize
set rtp+=~/.vim/bundle/vundle/
call vundle#begin()

" let vundle manage vundle, required
Plugin 'gmarik/vundle'

Plugin 'airblade/vim-gitgutter.git'
Plugin 'bling/vim-airline'
Plugin 'tpope/vim-commentary.git'
Plugin 'scrooloose/syntastic'
" Plugin 'Valloric/YouCompleteMe'

call vundle#end()

filetype plugin indent on

"""""""""""""""""""""""""""""
" Tabs
"""""""""""""""""""""""""""""
set tabstop=2
set shiftwidth=2
set softtabstop=2
set expandtab

"""""""""""""""""""""""""""""
" General Improvements
"""""""""""""""""""""""""""""
set t_Co=256
set encoding=utf-8
set scrolloff=3
set autoindent
set showmode
set showcmd
set hidden
set wildmenu
set wildmode=list:longest
set visualbell
set cursorline
set ttyfast
set ruler
set backspace=indent,eol,start
set laststatus=2
set relativenumber
set number
"set undofile

"""""""""""""""""""""""""""""
" Leader
"""""""""""""""""""""""""""""
let mapleader = ","

"""""""""""""""""""""""""""""
" Searching and Moving
"""""""""""""""""""""""""""""
set ignorecase
set smartcase
set gdefault
set incsearch
set showmatch
set hlsearch
nnoremap :noh
nnoremap %
vnoremap %

""""""""""""""""""""""""""""
" Long Lines
""""""""""""""""""""""""""""
set nowrap
" set textwidth=79
" set formatoptions=qrn1
" set colorcolumn=85

""""""""""""""""""""""""""""
" Invisible Characters (tabs, returns, etc.)
""""""""""""""""""""""""""""
" set list

""""""""""""""""""""""""""""
" Disable arrow keys
""""""""""""""""""""""""""""
" nnoremap
" nnoremap
" nnoremap
" nnoremap
" inoremap
" inoremap
" inoremap
" inoremap
" nnoremap j gj
" nnoremap k gk

"""""""""""""""""""""""""""
" Help Key Remap
"""""""""""""""""""""""""""
"inoremap
"nnoremap
"vnoremap

"""""""""""""""""""""""""""
" Save when not focus
"""""""""""""""""""""""""""
:au FocusLost * :wa
" set autowriteall

"""""""""""""""""""""""""""
" Fortran Free-form
"""""""""""""""""""""""""""
let fortran_free_source=1
let fortran_do_enddo=1

"""""""""""""""""""""""""""
" Automatically Close Delimiters
"""""""""""""""""""""""""""
" inoremap {     {}
inoremap { {}O
inoremap {{ {}
inoremap {} {}

" inoremap (     ()
inoremap ( ()O
inoremap (( ()
inoremap () ()

" inoremap [     []
inoremap [ []O
inoremap [[ []
inoremap [] []

" inoremap [ []O
inoremap '' ''
inoremap "" ""
" inoremap [] []

""""""""""""""""""""""""""""
" ColorSchemes
""""""""""""""""""""""""""""
set background=dark
colorscheme gruvbox

""""""""""""""""""""""""""""
" Enable Mouse
""""""""""""""""""""""""""""
set mouse=a

syntax on
""""""""""""""""""""""""""""
" Delete buffer without closing split
""""""""""""""""""""""""""""

let g:airline#extensions#tabline#enabled=1
" let g:airline_powerline_fonts=1


nmap ,d :b#bd#

:nnoremap :let _s=@/:%s/\s\+$//e:let @/=_s:nohl

Thursday, September 3, 2015

Plotting From Fortran

Fortran does not automatically allow for plotting during execution.  There is a work around.  I touched on this with my previous post about plotting with gnuplot from python.  The same principles apply here.

From fortran call gnuplot.  For instance, to make a vector plot from fortran use the command

call system('gnuplot Vector.gp')

where Vector.gp is the gnuplot setup file for vector plotting.

This also requires a datafile that gnuplot can read.  I prefer a csv file because I can put that directly into other programs like excel as well.

So what I've done, is built an IO module with several subfunctions that will create a datafile for gnuplot and call the system for me.  More plot types are on the way.  See attached for details.

example scatter plot colored by the vorticity:
call cScatter(x,y,omegaz)

Fortran-GnuPlot Plotting.zip

By the way, I've switched to Atom text editor by github for my programming.  The .gp files I included save as .png files so I can use them with both word and latex.  Atom will open .png directly inside the editor and update as the figure updates.  This is approaching an IDE and it's a lot faster to update the figure than with Windows Image Viewer.  It should be a cross-platform solution too.

Thursday, August 6, 2015

Alternative Approach for Using Gnuplot with Python in Windows

I ran into a problem plotting with python in windows.  I don't know how common this problem is, but here were a few articles about it.  2 problems

First: matplotlib would crash (not respond) when trying to update the plot in a loop so that I could visualize data as it's generated.

Second: because windows command prompt doesn't play well with -persist, the well-known Gnuplot.py couldn't open a figure, display the data, then continue the code without closing the figure.  The figure has to be manually closed (or closed from command or not using persist) before the code would continue.  The other option is to use the png terminal to generate a png image that can be viewed outside either python or gnuplot.

This gave me an idea - but not for python.  In windows, windows photo viewer automatically updates if the image it's viewing is updated.  So I thought, why not generate a single png file that is viewed in windows photo viewer and let windows photo viewer update the image in real time.  This works as long as the png can be written and viewed before the next one is written.

So if I can do this with python, why couldn't I do it in Fortran too?

Here's my idea:  Make a module that has two functions.  First, one that takes variable arguments with column data and parses it in the correct form for gnuplot csv ( columns next to each other for each variable) and writes the data to a .dat file.  The second takes data and a gnuplot script name and calls the first to generate the correct data and then executes the load 'gnuscript.txt' command.

This is a bit redundant in python but I decided to use it as a first step towards something better.  Since fortran doesn't visualize data on any operating system (easily at least), this approach would be extensible to other OS.

Attached is a python collection with gnuplot scripts to generate several common figures.

GnuPlotLib.zip

Monday, February 16, 2015

Installing Fortran on Windows with MinGW

As a followup to the previous post using cygwin to emulate linux to install gfortran, this post is the same but using mingw.  From my own experience, cygwin worked on 2/3 of the computers I installed it on.  On the third, it was unusably slow - 2-3 minutes to open terminal.  The instructions online to speed things up were unhelpful - my problem was not addressed.  Fortunately, there is also minwg that does the same thing from the perspective of a scientist that needs a compiler (CS guys might disagree but their purpose would be different).  The biggest difference between the two is that mingw compiles programs to be run on windows while cygwin works on cygwin.

This post is more for me to aggregate the hard work of others so I have a single place to look when installing Fortran on Windows.

Here's the gist:

1) make sure you've got Java installed if you use Eclipse (or other Java-based IDEs) http://www.oracle.com/technetwork/java/javase/downloads/index.html

2) download MinGW from www.mingw.org .  Click Downloads on the left and Download the latest version setup.exe file from sourceforge

3) install minwg as administrator to the c:\ drive.

4) I installed all the packages in the basic setup options (developers kit, base, ada, fortran, c++, object c, msys base)

these will get you started.  The g++ compiler is also available and eventually, installing all pthreads packages will get openMP running.

5) Add path variables:
;C:\MinGW\bin;C:\MinGW\msys\1.0\bin\

5) Check that gfortran is installed by typing gfortran --version into windows command prompt or terminal.  The terminal is in C:\MinGW\msys\1.0  msys.bat opens it.

6) Install Eclipse Parallel tools developer kit (containing Photran) http://www.eclipse.org/ptp/
if you had a previous project running in cygwin, you'll probably have to open a new project so the new addresses for the compilers will be recognized.

Sunday, February 15, 2015

Installing Fortran on Windows with Cygwin

This post is more for me to aggregate the hard work of others so I have a single place to look when installing Fortran on Windows.

This set of instructions is where I got most of my help.  There are a couple tweaks that were necessary to keep everything up and running on 64bit with newer packages.  After all, the video is a couple years old.
https://www.youtube.com/watch?v=GfCmiEbGtpE

Here's the gist:

1) make sure you've got Java installed if you use Eclipse (or other Java-based IDEs) http://www.oracle.com/technetwork/java/javase/downloads/index.html

2) download cygwin from www.cygwin.org .  Download the setup.exe file for either 32 or 64 bit systems

3) install cygwin as administrator to the c:\ drive.  The cygwin.mirrors.hoobly.com mirror definitely works.

4) Install these packages in cygwin:
gcc-fortran: GNU Compiler Collection
gdb: The GNU Debugger
make: The GNU version of the 'make' utility

these will get you started.  The g++ compiler is also available and eventually, I (you) might need either OpenMP or OpenMPI.

5) Add path variables:
for 64 bit
;C:\Cygwin64\bin;C:\Cygwin64\usr\bin;C:\Cygwin64\usr\local\bin;C:\Cygwin64\lib;C:\Cygwin64\usr\lib
or for 32 bit
;C:\Cygwin\bin;C:\Cygwin\usr\bin;C:\Cygwin\usr\local\bin;C:\Cygwin\lib;C:\Cygwin\usr\lib

5) Check that gfortran is installed by typing gfortran --version into command prompt

6) Install Eclipse Parallel tools developer kit (containing Photran) http://www.eclipse.org/ptp/

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'.

Tuesday, March 1, 2011

Sage Server Through VMware

Sage is a open source frontend and server that I use to replace Mathematica in particular, but will also serve as a frontend for Mathematica, Matlab, Latex, Python (it's foundation), and more. It is almost powerful enough to completely replace Mathematica as an analytic mathematics software. It's really close. It surpasses Mathematica in the ease and speed in which you can do real coding for numerical mathematics as well. It uses Python, numpy and scipy so all the standard Matlab stuff is included. It spits out really nice figures too. The server side is one of the best parts! Documentation is kinda poor to get the install right but once you do, it will automatically store accounts and log in information for multiple simultaneous users. It's browser based, so you never have to install anything on your personal machine and it just so convenient!

Enough about that! The biggest problem - poor documentation for the novice since it doesn't have a Windows version. It has a virtual machine version and ok documentation to install with Windows as the host but screw that! If you're a research group or company, I would forgo all the VMware stuff I'm including here and just build a dedicated Linux server. You'll get more performance, less set up, and you can use it to run all kinds of other code scripts so each client machine doesn't have to have all that garbage installed.

I had help setting my instance from this document. I did things a little differently and that's why i'm posting about it now.

  • Install VMware. Get VMware. We had a copy of VMware Workstation that was unused so I know it works. Virtual Box probably works too.
  • Install Linux on VMware. I installed Ubuntu x64. Overall, Ubuntu is the least foreign to my simple Windows using mind;). File-New-Virtual Machine-Install from iso-follow the onscreen directions
  • If this is a VMware install, I assume this is a test bed and not a full implementation. If this is true, select the amount of RAM and Disk Space you want to allocate in the OS settings through VMware. The Network Adapter should be set to Bridged: Connect directly to the physical network. The checkbox "Replicate physical ..." is unchecked. This step is important for assigning a unique IP address to the Virtual Machine so it can be accessed directly and not just through the host.
  • Install an ssh server. Sage is a command line software (so is Mathematica, Matlab, Python...etc) with a frontend attached. Command line access through ssh can be helpful if you want to remotely run code...any code...not just sage...so I recommend doing this regardless of what you plan on putting on your server. Do this with sudo apt-get install openssh-server
  • Download Sage from sagemath.org. Make sure you get the right version for your operating system.
  • Install. I never remember how to install anything in Linux...I can't understand why Linux operating system designers make it so damn complicated. I think the correct install command for sage is sudo ./ but it might simply be sudo ./sage ...I don't really remember but I think it actually just extracts somewhere and is done so you might want to make sure the install file is already in the folder you want the final install in...I just can't remember. It might actually have a debain package that "just works" when you double click it.
  • Test to make sure it installed. open terminal and type the word "sage" you should get a sage: prompt. If you type notebook() a web browser should pop up with the generic server index page. More specifically type notebook(address='',port=8000,accounts=True) to start a server on that ip with that port and user accounts enabled.
  • To really make this a server, it is convenient to set up some symbolic links. Enter (from the document linked above)
cd
ln -s sage
cd /usr/local/bin
sudo ln -s /sage sage
sudo ln -s /local/bin/sage-python sage-python
cd
Here, is the full path to the Sage directory, something
like:
/home//sage-3.2.1-etc...
To test the links, go to your home directory and type:
sage
This should start Sage. Then enter:
sage-python
This will start the version of Python that comes with Sage.

  • Now we want a script to start the server with all the options already set. I'm not sure if it has to be a Python script but Python plays nice with Linux and that's a good thing. In the home directory make a file called notebook.py with the following commands inside
from sage.all import*
notebook(address='XXX.XXX.XX.XXX',port=8000,accounts=True)

all the Xs are for the IP address of the virtual machine. make sure the apostrophes are included. accounts=True allow for private user accounts to be created on the server. When you run this script terminal will give an error about being crazy if you don't have secure=True but True seems to disallow access over the internet.

  • Start the server with sage-python notebook.py
  • Make a launcher from the desktop. I think there is a way to have the server start with the machine but I'm to dumb to use Linux. My small brain can only hand simple Windows and the super convenient Startup folder. If you're like me, right click on the desktop and create launcher. It's either type: application or application in terminal. I don't remember. and the command: sage-python notebook.py
  • THIS STEP PROBABLY ISN'T NEEDED FOR BRIDGED NETWORK ADAPTERS. From Windows go to Allow program through firewall and open port 8000 in UDP and TDP.
  • The server can now be accessed through any web browser by typing http://XXX.XXX.XX.XXX:8000 or by pointing any ssh client to the same address
Sage is sweet! I can access and share my personal notebooks through any browser - including my phone. You can make really professional documents and reports directly in a web browser if you know a little html programming too. I hope this project continues. It is one of the most remarkable examples of how open source software can actually be very good!

Sunday, February 6, 2011

Python: The Division Sign

I've been wrong all these years! I'd always thought 3/2=1.5 . Apparently, it's actually 3/2=1. Much like pi=3 to the Alabama state legislature instead of pi=3.14159... (see the joke).

Clearly this is "wrong" (at least for scientific computing and arguably everywhere else) but here's why this happens. It's the difference in how the data types are defined - the output depends on the input types so

3/2=1 because 3 and 2 are int (integer) type so the output is a truncated integer. This is "floor division" and is how C does it too. However,
3.0/2=1.5 because 3.0 is a float so the output is a float even though 2 is still typed in as an int. I think it's actually a float now too but i'm not sure.

Starting with Python 2.2 a new division operator is introduced. Now
3/2=1.5
3//2=1

The "//" is now the floor division and the single "/" will be true division. I think Python 3 will have this completely integrated but all us 2.x users we're still SOL unless we want to rework all our codes.

Solution: import a module to overwrite the division sign with the upcoming (and computationally relevant) definition. At the very top include the statement

from __future__ import division

now the "/" will always be true division.

This module probably has a bunch of other important stuff. Since i'm learning python right before these all become standards is there a way to import ALL the future commands so I don't have to relearn anything when 3.x if viable for me? Something like from __future__ import * would be nice!

Python: Matplotlib for 64bit

If you have 64bit python installed...I used the Enthought package to do it...Matplotlib probably won't actually work because it's not available for 64bit in general. So when you try to plot something you get a huge error output. If you look closely, the only real error is that it can't find a font in the "show()" command because it's looking in the (x86) directory. The brute force fix - find the correct subdirectory in the 64 bit install directory and copy it into the equivalent 32 bit install directory. In short:
Copy
C:\Program Files\Python26\Lib\site-packages\matplotlib
Create/Paste
C:\Program Files (x86)\Python26\Lib\site-packages\matplotlib

duh as in done!

I have a feeling all that needs to be done is add/change the path so it can find the right folders anyway. If anyone reads this and can confirm, please comment. Thanks!

Python: Tips for Matlab Users: Standardizing Syntax

Remember how in Matlab you have to call libraries and denote commands with prefixes referring to the library they are hosted in? You don't? Because you DIDN'T:). You do in python though. This is really because python is not originally a scientific computing software but it is supposed to allow for addons, packages, and all kinds of extension including scientific computing. Interestingly enough, this is also the way to call functions from other py files (that's vaguely familiar in Matlab).

But python is a similar to C with respect to loading headers and similar to Matlab in the implementation. Like C we have to import our "modules" or "libraries" (same thing) or specific "functions." Before an example read this article about the "from" and "import" commands.

For our an example, lets solve a complex generalized eigenvalue problem, calculate the execution time and plot the spectrum. We need scipy (numpy can only do single matrix eigenvalue problems) and a time function. More specifically, we need the eig() function inside the linalg library in scipy.

First the correct and safe way:
Here we want to import the eig() function from the scipy.linalg library, then prefix all scipy commands with "sc" in case we want to use modules with conflicting function names. This requires two import statements. One for the special function eig and one to denote the scipy commands.
Next we want the plot library available so we import the matplotlib.pyplot with the prefix plt. The pyplot is the special collection of functions inside matplotlib to make nice plots - just like eig was in the linalg library in scipy. Finally we want to import the time function
Now we define the matrix size and generate random NxN complex matrices A and B. Start the clock. Compute the eigenvalues and eigenvectors (L,V). Generate the figure and define the active object number. Scatter plot the spectrum. Force the plot to draw. Display the calculation time. All this is shown below.

################################################
import scipy as sc
from scipy.linalg import eig

import matplotlib.pyplot as plt
import time

N=50
A=sc.random.random((N,N))+sc.random.random((N,N))*1j
B=sc.random.random((N,N))+sc.random.random((N,N))*1j
tic = time.time()
(L,V) = sc.linalg.eig(A,B)
toc = time.time()
print toc-tic, " has passed"
plt.figure(1)
plt.scatter(sc.real(L),sc.imag(L))
plt.show()
################################################

Notice how i use the sc prefix on every scipy command. This might be important if i'm also using built in sympy commands with the same function names...but i'm not. Let's do this again. This time no prefixes.

################################################
from scipy import *
from scipy.linalg import *
from matplotlib.pyplot import *
from time import *

N=50
A=random.random((N,N))+random.random((N,N))*1j
B=random.random((N,N))+random.random((N,N))*1j
tic = time()
(L,V) = eig(A,B)
toc = time()
print toc-tic, " has passed"
figure(1)
scatter(real(L),imag(L))
show()
################################################

The from import * commands give access to all the functions in the library...not just the eig function... and with no prefixes. The random still has a prefix and i'm not sure why or how to make it go away but I started learning python about 48 hours ago so oh well. Either way, this is similar syntax to matlab so python should be a viable alternative!

FYI run times for both are about the same for the eig command with both running 64 bit versions.

Saturday, February 5, 2011

Python: Tips for Matlab Users: Getting Started with Python

Engineers are not computer scientists and as such Matlab is perfect for us guys that don't want to screw around with nonsensical syntax. Computer science guys are so damn pretentious about their programing languages i'm sure some of them will read this and get a little red in the face. Let's face it though; our job is NOT to write elegant codes. Our job is to solve practical engineering and applied mathematics problems. With Matlab, we don't have to spend an hour trying to find where the damn missing bracket is supposed to go (i hate you most c and c++ lol). It's clean, simple, powerful, and it just works. The trade off is speed...sometimes...

Enter python and more specifically numpy, scipy, ipython, and matplotlib.

But first - why python? Beats me...but it was recommended to me. That's not 100% true though. Mostly it's simplicity of syntax compared to c and built in fortran wrappers for those awesome Lapack, Linpack, Blas...(idk if they are all fortran but whatever...they are all there). In fact with a little set up, the python commands can be reduced to nearly the same as Matlab.

Problem #1: As of early 2011 python is experiencing a large overhaul from v2.x to v3.x but numpy, scipy, and matplotlib aren't ported yet.

Problem #2: The sponsored numpy download installs over python 2.6 - python 2.7 is the currently available release. Idk where 2.6 is hosted.

Problem #3: Scipy needs numpy. Scipy installs over python 2.7. Numpy installs over 2.6. Scipy can't be installed since numpy can't be installed.

I could probably figure out #2 and 3 but back to the original statement - why should I have to. You developers are the computer science guys. If that's the best you can do...then I hope you never get hired to develop something for the general public!

Solution: Enthought. It packages it all together with one install so you don't have to screw around. Everything mentioned here is for fundamental scientific computing and visualization so specialized packages may or may not be available in python. Enthought has 32 and 64 bit versions and if you have a 64 bit operating system definitely use the 64bit version or else you won't have the same speed optimization that Matlab offers. In reality Enthought probably doesn't offer anything unique but it simplifies and consolidates the install process. It's not free (academic licenses are) but it's a hell of a lot cheaper than Matlab!