Showing posts with label MATLAB mayhem. Show all posts
Showing posts with label MATLAB mayhem. Show all posts

Thursday, May 14, 2015

[MATLAB] Do *not* use `obj.empty` to preallocate object array

FYI: You do not need to use `obj.empty` to preallocate an object array.

In fact as soon as you assign a value to any element in the object array it grows the array to that size, which allocates (or reallocates) RAM for the new object array, therefore defeating the point of preallocating space.

From Empty Arrays section of OOP documentation:

“If you make an assignment to a property value, MATLAB calls the SimpleClass constructor to grow the array to the require size:”

Instead if you want to preallocate space for an object array, grow the array once by assigning the last object first. This requires the class to have a no-arg constructor. Each time you grow your array you will reallocate RAM for it, wasting time and space, so do it once with the max expected size of the array. See Initialize Object Arrays and Initializing Arrays of Handle Objects in the OOP documentation.

  >> S(max_size) = MyClass(args)

Another option is to preallocate any other container like a cell array (best IMHO), structure or containers.Map and then fill in the class objects as they are created. An advantage to this is you don’t have to subclass matlab.mixin.Heterogeneous to group different classes together.

  >> S = cell(max_size); args = {1,2,3;4,5,6;7,8,9};
  >> for x = 1:size(args,1), S(x) = MyClass(args{x,:});end

The only time to use an empty object is if you want it as a default for the situation where nothing gets instantiated, and you need the it be an instance of the class. Of course any empty array will do this, IE: '', [] and {} are also empty.

  >> S = MyClass.empty
  >> if blah,S = MyClass(args);end
  >> if isa(S, 'MyClass') && isempty(S),do stuff; end

Another reason might be to clear defaults if the constructor is called recursively, although obj.delete will do the same thing.

I hope this helps someone; it definitely helped me understand the odd nature of MATLAB. This behavior is because everything in MATLAB is an array, even a scalar is a <1x1 double> read the C-API mxArray for external references and mwArray for compiled/deployed MATLAB for more info.

MATLAB = Matrix Laboratory
Class definitions didn’t appear until 2008. Other languages like C++, Java, Python and Ruby are object first. So the empty method is meant to duplicate the ability to be empty similar to other MATLAB datatypes such as double, cell, struct, etc. IMO outside of MATLAB it's a very artificial and somewhat meaningless construct.

Monday, March 16, 2015

Upgrade to Visual Studio 2013 Express

Welcome to the future. It's nice of you to join us. Have you been limping along with very old outdated C/C++/C# toolsets? Still using Visual Studio 2010? 2008? Afraid to uninstall them for fear you will lose the ability to compile your projects. Let's take care of that right now, don't worry about a thing. In about 1-2 hours, you will be happily in the future, enjoying the modern conveniences of Visual Studio 2013. It's very nice here. Won't you join us?
  1. Remove Visual Studio 2010 SP1 and run the uninstall utility
  2. NameSizeVersion
    Microsoft Visual Studio 2010 Service Pack 175.9 MB10.0.40219
    Microsoft Visual C++ 2010 Express - ENU10.0.40219
    Microsoft Visual C# 2010 Express - ENU10.0.40219
    Microsoft Visual Studio 2010 Express Prerequisites x64 - ENU21.6 MB10.0.40219

    You can follow the instructions I posted in the 3/13/2015 update to Download sites for old, free MS compilers and IDEs but the system restore point has dubious value. In fact it didn't help at all. When I was in trouble I found myself reinstalling the application then removing it again in the correct order. The key here is to uninstall SP1 first, then use Stewart Heath's VS2010 uninstall utility in default mode. If you find yourself in trouble, reinstall VS2010 and VS2010-SP1. If you need installers I have them here in my dropbox.

  3. Remove Visual Studio 2008 SP1.
  4. NameSizeVersion
    Microsoft Visual C++ 2008 Express Edition with SP1 - ENU

    Same here, make sure you have an installer. The web installer in my dropbox still works surprisingly. Any trouble, reinstall and uninstall again.

  5. Remove both SDKs for Windows 7 and .NET Frameworks 3.5 and 4.0
  6. NameSizeVersion
    Microsoft SDK for Windows 7 (7.1)7.0.7600.16385.40715
    Microsoft SDK for Windows 7 (7.0)7.1.7600.0.30514

    If you have any issues with this, look at the last entry in the log. There's a View Log button when setup fails next to the Finish button. A part of the SDK that the installer is looking for may be missing. Search for the keyword "fail" and "unknown source". If you find an unknown source in the log file, download and extract the ISO from the SDK archives page and run the installer for the missing component. Any archive client will work. I use 7-zip 9-22beta. For SDK 7.0 I had to reinstall Intellidocs before I could completely remove the SDK. And for SDK 7.1 I had to install the Windows Performance Toolkit to remove the SDK completely. Only the ISO will work here, not the redistributables.

    Also beware of the Microsoft Install/Uninstall Fixit it doesn't actually do anything but clean your registry. It removed both SDKs but then wouldn't let me reinstall them, all of the files were still in C:\Program Files\Microsoft SDKs\Windows\v7.x all that was different was that they were not in the add/remove programs control panel.

  7. Remove everything else
  8. NameSizeVersion
    Microsoft Document Explorer 2008
    Microsoft Help Viewer 1.13.97 MB1.1.40219
    Microsoft SQL Server 2008 R2 Management Objects12.4 MB10.50.1750.9
    Microsoft SQL Server Compact 3.5 SP2 ENU3.39 MB3.5.8080.0
    Microsoft SQL Server Compact 3.5 SP2 x64 ENU4.50 MB3.5.8080.0
    Microsoft SQL Server System CLR Types930 KB10.50.1750.9
    Application Verifier (x64)55.3 MB4.1.1078
    Debugging Tools for Windows (x64)39.8 MB6.12.2.633
    Microsoft Visual Studio 2008 Remote Debugger light (x64) - ENU
    Microsoft Visual Studio 2010 ADO.NET Entity Framework Tools34.2 MB10.0.40219
    Microsoft Visual Studio 2010 Tools for Office Runtime (x64)10.0.50903
    Microsoft Windows Performance Toolkit26.1 MB4.8.0
    Microsoft Windows SDK for Visual Studio 2008 Headers and Libraries114 MB6.1.5288.17011
    Microsoft Windows SDK for Visual Studio 2008 SP1 Express
    Tools for .NET Framework - enu
    4.41 MB3.5.30729
    Microsoft Windows SDK for Visual Studio 2008 SP1 Express
    Tools for Win32
    2.61 MB6.1.5295.17011

    As you can see there is a lot of detritus left behind.

  9. Remove the 2008 & 2010 C++ compilers and the Visual C++ 2010 SP1 redistributables.
  10. NameSizeVersion
    Microsoft Visual C++ Compilers 2008 Standard Edition - enu - x64127 MB9.0.30729
    Microsoft Visual C++ Compilers 2008 Standard Edition - enu - x86321 MB9.0.30729
    Microsoft Visual C++ Compilers 2010 SP1 Standard - x64206 MB10.0.40219
    Microsoft Visual C++ Compilers 2010 SP1 Standard - x86613 MB10.0.40219
    Microsoft Visual C++ 2010 x64 Redistributable - 10.0.402196.86 MB10.0.40219
    Microsoft Visual C++ 2010 x86 Redistributable - 10.0.402195.44 MB10.0.40219

    These will be reinstalled later. You can not install Windows SDK for Windows 7 (7.1) with NET 4.0 Framework if you already have the Visual C++ 2010 SP1 redistributable installed or you will get the dreaded error 5100.

  11. Reinstall both SDKs
  12. Use the web installers linked from the SDK archives page.

  13. Install C++ compiler for Python 2.7 and patch vcvarsall.bat
  14. The standalone Python compiler will install the VS2008 (VC90) compilers and headers as well as the vcvarsall.bat batch file that sets environment variables necessary to build Python packages on the fly using pip and setuptools>=6.0. However to build packages using distutils, i.e.: python setup.py build you will need to patch vcvarsall.bat in your C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC directory. To do this copy the vcvarsall.txt file that the SDK created as vcvarsall.bat, then patch it with the Gist in my post. i.e.: patch vcvarsall.bat vcvarsall.bat.patch in bash after downloading and extracting the Gist.

  15. Reinstall the Visual C++ 2010 redistributables for x64 and x86
  16. Install the Microsoft Visual C++ 2010 SP1 compiler update for Windows SDK 7.1
  17. Install VS2013 Express with Update 4 or the free VS2013 Community edition.
  18. The Express edition only has VB, C# and C/C++ compilers, and does not allow extensions, whereas the community edition has everything, but is restricted for commercial use in large corporations.

Voila!

Thursday, March 12, 2015

sqlite in MATLAB

It turns out that MATLAB has sqlite builtin
% get or create a new database
db = com.almworks.sqlite4java.SQLiteConnection(java.io.File('sample.db'))
db.open % open database

% create a table called “person” with 2 columns, name and id
db.exec('create table person (id integer, name string)')

% add rows to “person” table
db.exec('insert into person values(1, "leo")')
db.exec('insert into person values(2, "yui")') 
db.dispose % dispose of db handle

% optionally close and reopen database to see it persists
db = com.almworks.sqlite4java.SQLiteConnection(java.io.File('sample.db'))
db.open

% create a prepared statement with ? wildcard
st = db.prepare('select * from person where id>?')
st.bind(1,0) % bind 1st ? wildcard to any number greater than 0

% binding the prepared statment also works for strings
% st = db.prepare('select * from person where name>=?')
% st.bind(1,'') % bind 1st ? wildcard
% note: all string are greater than or equal to ''

% step through matching rows
while st.step
  % returning the data type from the desired column
  st.columnInt(0) % get IDs from column 0
  st.columnString(1) % get name from column 1
end

% disposed of used up statement container
st.dispose
st.isDisposed

% ditto for db connection
db.dispose
db.isDisposed

% output
ans = 1
ans = leo
ans = 2
ans = yui
Although IMO xerial’s jdbc driver (with sqlite included) is much easier
% https://bitbucket.org/xerial/sqlite-jdbc/wiki/Usage 
javaaddpath('C:\Users\mmikofski\Documents\MATLAB\sqlite\sqlite-jdbc-3.8.7.jar')
d = org.sqlite.JDBC
p = java.util.Properties()
c = d.createConnection('jdbc:sqlite:sample.db',p) % named file

% optional connections
% c = d.createConnection('jdbc:sqlite:C:/full/path/to/sample.db',p) % full path
% c = d.createConnection('jdbc:sqlite::memory:',p) % memory db
% c = d.createConnection('jdbc:sqlite:',p) % default
s = c.createStatement() % create a statement

% create a table, insert rows, etc.
% s.executeUpdate('create table person (id integer, name string)');
% s.executeUpdate('insert into person values(1, "leo")');
% s.executeUpdate('insert into person values(2, "yui")');

% execute query, get id and name
rs = s.executeQuery('select * from person')
while rs.next
    rs.getString('id')
    rs.getString('name')
end
c.close % close connection
c.isClosed

% output
ans = 1
ans = leo
ans = 2
ans = yui

Friday, January 9, 2015

Questionable Quantities in MATLAB

I am proud to introduce Quantities for MATLAB. Quantities is an units and uncertainties package for MATLAB. It is inspired by Pint, a Python package for quantities.

Installation

Clone or download the Quantities package to your MATLAB folder as +Quantities.

Usage

  1. Construct a units registry, which contains all units, constants, prefixes and dimensions.
  2.     >> ureg = Quantities.unitRegistry
    
      ureg = 
    
      Map with properties:
    
            Count: 279
          KeyType: char
        ValueType: any
    
  3. Optionally pass verbosity parameter to unitRegistry to see list of units loaded.
  4.     >> ureg = Quantities.unitRegistry('v',2)
    
  5. Units and constants can be indexed from the unitRegsitry using their name or alias in parentheses or as dot-notation. The unit, constant and quantity class all subclass to double so you can perform any operation on them. Combining a double with a unit creates a quantity class object.
  6.     >> T1 = 45*ureg('celsius') % index units using parentheses or dot notation
        T1 =
            45 ± 0 [degC];
    
        >> T2 = 123.3*ureg.degC % index units by name or by alias
        T2 =
            123.3 ± 0 [degC];
    
        >> heat_loss = ureg.stefan_boltzmann_constant*(T1^4 - T2^4)
        heat_loss =
            -819814 ± 0 [gram*second^-3];
    
  7. Perform operations. All units are converted to base.
  8.     >> T2.to_base
        ans =
            396.45 ± 0 [kelvin];
    
        >> heat_loss = ureg.stefan_boltzmann_constant*(T1.to_base^4 - T2.to_base^4)
        heat_loss =
            -819814 ± 0 [gram*second^-3];
    
  9. Add uncertainty to quantities by calling constructor. Uncertainty is propagated using 1st order linear combinations.
  10.     >> T3 = Quantities.quantity(56.2, 1.23, ureg.degC)
        T3 =
            56.2 ± 1.23 [degC];
    
        >> heat_loss = ureg.stefan_boltzmann_constant*(T1^4 - T3^4)
        heat_loss =
            -86228.1 ± 9966.66 [gram*second^-3];
    
  11. Convert output to different units.
  12.     >> heat_loss_kg = heat_loss.convert(ureg.kg/ureg.s^3)
        heat_loss_kg =
            -819.814 ± 0 [kilogram*second^-3];
    
  13. Determine arbitrary conversion factor.
  14.     >> conversion_factor = ureg.mile.convert(ureg.km)
        conversion_factor =
            1.60934 ± 0 [kilometer];
    
MATLAB Syntax Highlighter brush by Will Schleter

Tuesday, November 25, 2014

Convert Excel row-column reference to A1 in MATLAB

I'm sure there are many of these snippets out there. Here is yet another one.
>> rc2a1(23,196)
GN23
Enjoy. Please don't use it for evil.

Friday, August 22, 2014

memcached MATLAB

UPDATE: 2015-03-10 - I was able to get spymemcached to work, which is very nice because it is

  • very fast
  • the first java client listed on the memcached wiki
  • it is by the same folks who ported memcached to Windows
  • has many, many options
  • the most current, updated to 2.11.6 this January-2015
.

Introduction

memcached is great for sending objects from process to process. I was able to use memcached to set and retrieve objects from two different instances of MATLAB. Here I used both Java and .NET libraries.

Downloads

I compiled Windows binaries of memcached-client libraries for both the Java and .NET using Java-1.7 and Visual Studio 2010 and zipped them up here.

The memcached server was compiled by Trond Norbye from Couchbase (previously Membase previously Northscale) for  32-bit and 64-bit Windows OS. See below how to run it as a service using the Python PyWin32 package.

.NET

Details

Memcached server version 1.4.5 patched for 64-bit Windows by Trond Norbye from Couchbase (previously Membase previously Northscale).
Memcached .NET client: Memcached.ClientLibrary port of com.meetup.memcached from sourceforge.

Build

Microsoft Visual Studio 2010 C# - Release/AnyCPU configuration. Since the original project files were for MSVC-8, MSVC-10 started an conversion wizard that first backed up the previous project files and then created a new MSVC-10 project files including a new solution file. Then I only build the clientlib_2.0 project from the MSVC-10 IDE GUI using build from the menu, and voila a new dll.

Usage

  1. Start memcached server
  2. C:\> C:\path\to\memcached.exe -vv
    
  3. Do this on both MATLAB instances
  4. >> asm = NET.addAssembly('C:\full\path\to\Memcached.ClientLibrary.dll')
    >> pool = Memcached.ClientLibrary.SockIOPool.GetInstance()
    >> pool.SetServers({'127.0.0.1:11211'})
    >> pool.Initialize
    >> mc = Memcached.ClientLibrary.MemcachedClient()
    
  5. MATLAB instance #1
  6. >> mc.Set('name','mark')
        1
    
  7. MATLAB instance #2
  8. >> mc.Get('name')
    mark
    

Java

MATLAB and memcached also works perfectly with the original meetup.com Java version that the .NET version was ported from. The commands are exactly the same as the .NET version.

Source:

com.meetup.memcached

Build:

There are two branches in Greg Whalin's GitHub repository: master and performance. Performance is more recent and uses a Schooner client which they benchmark against the older meetup.com (Whalin) client as well as spymemcached (Couchbase/Membase) and xmemcache (see below), and on the wiki pages and in a powerpoint presentation in the doc folder they report that the performance branch is allegedly faster.

You can build the performance branch either from the repo, or download a zip file of the Memcached-Java-Client-3.0.0 release from the downloads page. There are several required libraries to make this run in the lib folder of the performance branch also included in the zip-file or tar-ball.

I was able to build this using jdk-7 by ...

  1. extracting the file,
  2. making a new bin folder at the same level as lib and src,
  3. then navigating to src\main\java
  4. and executing the following:
  5. C:\> "C:\Program Files\Java\jdk1.7.0_55\bin\javac.exe" -verbose -cp ..\..\..\lib\commons-pool-1.5.6.jar;..\..\..\lib\slf4j-api-1.6.1.jar;..\..\..\lib\slf4j-simple-1.6.1.jar -sourcepath com\schooner\MemCached\ -source 1.6 -target 1.6 -d ..\..\..\bin com\whalin\MemCached\*.java com\schooner\MemCached\*.java com\schooner\MemCached\command\*.java
    
  6. Then back up to the new bin folder an executing this:
  7. c:\> "C:\Program Files\java\jdk1.7.0_55\bin\jar.exe" -cvf Memcached-Java-Client.jar com\
    
There are also newer jar files (3.0.2) from the Maven repository. All of the newer performance branch versions (3.0.0 and 3.0.2) work almost exactly like the old meetup.com client, but the package is named com.whalin.MemCached instead. Also now you will also have to add commons-pool-1.5.6.jar, slf4j-api-1.6.1.jar and slf4j-simple-1.6.1.jar to your MATLAB Java classpath using javaaddpath(). Finally the logger output is cleaned up so that you don't have to set up any logger properties as in the master branch. In fact if you do want to set up logging properties, the new performance branch doesn't use apache.org.log4j it uses slf4j simple logger.
>> javaaddpath('C:\full\path\to\commons-pool-1.5.6.jar')
>> javaaddpath('C:\full\path\to\slf4j-api-1.6.1.jar')
>> javaaddpath('C:\full\path\to\slf4j-simple-1.6.1.jar')
>> javaaddpath('C:\full\path\to\Memcached-Java-Client-3.0.2.jar')
>> import com.whalin.MemCached.MemCachedClient
>> import com.whalin.MemCached.SockIOPool
>> pool = SockIOPool.getInstance;
>> pool.setServers({'127.0.0.1:11211'})
>> pool.initialize
>> mc = MemCachedClient;
>> pool.getAliveCheck
    1
>> mc.set('name','mark')
    1
>> mc.get('name')
mark
>> pool.shutDown
>> pool.getAliveCheck
    0
You can also build the master branch from the Github source.
$ /c/Program\ Files/Java/jdk1.7.0_55/bin/javac.exe -verbose -classpath ../lib/log4j.jar -sourcepath com/meetup/memcached/ -source 1.6 -target 1.6 -d ../bin/ com/meetup/memcached/*.java
$ /c/Program\ Files/Java/jdk1.7.0_55/bin/jar.exe -cvf MeetupMemcached.jar com/
In the master branch, the Apache logger is not cleaned up for the non-bench/test sources (with isErrorEnabled(), etc. see jlog4 documentaion), so you always get this error message:
log4j:WARN No appenders could be found for logger (com.meetup.memcached.SockIOPool).
log4j:WARN Please initialize the log4j system properly.
Because there are log calls in the MemcachedClient and SockIOPool files that never have BasicConfiguration.configure() or set any jlog4.<properties> like the appender hence the error. Of course they never meant for log messages to be displayed when deployed, so wrapping with isErrorEnabled() like the .NET version does would be better. In order to get rid of that message and output logging messages to a file configure the Apache.org log4j logger yourself by creating a FileAppender with the default layout and then configuring the BasicConfigurator.
>> fileAppender_withDefaultLayout = org.apache.log4j.FileAppender(org.apache.log4j.PatternLayout,'memcached.log')
fileAppender_withDefaultLayout =
org.apache.log4j.FileAppender@60f585a2
>> org.apache.log4j.BasicConfigurator.configure(fileAppender_withDefaultLayout)
An optional boolean 3rd argument appends or overwrites the log file. Relative paths seem to be working so far, but full absolute path might be better.

Usage:

First start memcached server, then start sock IO pools and memcached clients on both matlab instances.
>> fileAppender_withDefaultLayout = org.apache.log4j.FileAppender(org.apache.log4j.PatternLayout,'memcached.log')
>> org.apache.log4j.BasicConfigurator.configure(fileAppender_withDefaultLayout)
>> javaaddpath('C:\full\path\to\MeetupMemcached.jar')
>> pool = com.meetup.memcached.SockIOPool.getInstance()
>> pool.setServers({'127.0.0.1:11211'})
>> pool.initialize
>> mc = com.meetup.memcached.MemcachedClient
>> mc.set('name','mark') % on 1st instance/process
    1
>> mc.get('name') % on 2nd instance/process
mark

Other clients

  • xmemcached - Github:killme2008, Google Code project and Maven repo
  • The Xmemcached client works well. It is the most recently updated. There are jar files on the releases page of the GitHub repo. Here is an example from the 2.0.0 release from this April. The example is from the google.code wiki User Guide in English.
    >> javaaddpath('C:\full\path\to\xmemcached-2.0.0.jar')
    >> addr = net.rubyeye.xmemcached.utils.AddrUtil.getAddresses('localhost:11211')
    addr =
    [localhost/127.0.0.1:11211]
    >> builder = net.rubyeye.xmemcached.XMemcachedClientBuilder(addr)
    builder =
    net.rubyeye.xmemcached.XMemcachedClientBuilder@7ef6a26
    >> mc = builder.build()
    log4j:WARN No appenders could be found for logger (net.rubyeye.xmemcached.XMemcachedClient).
    log4j:WARN Please initialize the log4j system properly. 
    mc = 
    net.rubyeye.xmemcached.XMemcachedClient@275e6ce5
    >> mc.set('name',0,'mark')
    ans =
         1
    >> mc.get('name')
    ans =
    mark
    
    To get rid of the logger message you will have to download SLF4J and add slf4j-api-X.Y.Z.jar, slf4j-simple-X.Y.Z.jar and slf4j-log4j-X.Y.Z.jar to your path first, where X.Y.Z is the SLF4J version, 1.7.7 as of 2014-08-27. Then configure log4j as above for com.meetup.memcached.
    >> fileAppender_withDefaultLayout = org.apache.log4j.FileAppender(org.apache.log4j.PatternLayout,'memcached.log')
    fileAppender_withDefaultLayout =
    org.apache.log4j.FileAppender@60f585a2
    >> org.apache.log4j.BasicConfigurator.configure(fileAppender_withDefaultLayout)
    
  • Enyim - NuGet and Github:enyim
  • I couldn't get this assembly to load as built, I always got an "Strong Name Validation Failed" error, perhaps because I am on a 64-bit machine, but using MSVC express.
  • spymemcached - Github:couchbase (was dustin), Google Code project and Maven repo
  • UPDATED: 2015-03-11 I finally get this to work. I used AddrUtil to make building the client easy, similar to xmemcached. Everything just works. Download the latest jar from Maven Central, from GitHib releases page or a somewhat older jar from the google code download page.
    >> javaaddpath('C:\Users\mmikofski\Downloads\spymemcached-2.10.3.jar')
    >> import net.spy.memcached.AddrUtil
    >> import net.spy.memcached.MemcachedClient
    >> mc = net.spy.memcached.MemcachedClient(net.spy.memcached.AddrUtil.getAddresses('localhost:11211'))
    
    2015-03-10 22:24:44.508 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=localhost/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
     
    mc =
     
    Failure Mode: Redistribute, Hash Algorithm: NATIVE_HASH Max Reconnect Delay: 30, Max Op Timeout: 2500, Op Queue Length: 16384, Op Max Queue Block Time10000, Max Timeout Exception Threshold: 998, Read Buffer Size: 16384, Transcoder: net.spy.memcached.transcoders.SerializingTranscoder@2a744425, Operation Factory: net.spy.memcached.protocol.ascii.AsciiOperationFactory@3725eee9 isDaemon: false, Optimized: false, Using Nagle: false, ConnectionFactory: DefaultConnectionFactory
     
    2015-03-10 22:24:44.514 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@7deebece
    
    >> mc.set('name',0,'mark')
    
    ans =
     
    net.spy.memcached.internal.OperationFuture@6126121f
    
    >> mc.get('name')
    
    ans =
    
    mark
    

    Seriously, could this be any easier?

    A lot of people have asked how to test if spymemcached connection is alive. This is because spymemcached will keep trying to connect or complete it's task even if it can't connect to the memcached server, which is nice if the server goes for a second then comes back up. There solution is to use a Future async task by calling their .asyngGet() method. Another way is to test the socket using java.net.Socket(inetAddress) which will raise an exception if it fails to connect.

    InetSocketAddress addr = new java.net.InetSocketAddress("localhost", 11211);
    try {
        Socket sock = new java.net.Socket(addr.getAddress, addr.getPort);
    } except (java.net.ConnectException) {
    ...;
    } else {
    sock.close();
    }
    

memcached server as Windows service

This is pretty easy using Python PyWin32 win32service.

Friday, May 2, 2014

loading MATLAB mat-file into Pandas

Pandas is a great tool for analyzing large data sets, especially time-series data. It quickly and easily imports most basic data files: Excel, comma-separated values, etc., but not MATLAB mat-files. However, SciPy does import MATLAB mat-files, so combining packages gets the job done.

Here's an example of a mat-file that has a single variable, called measuredData, that contains a MATLAB structure with a timeStamps field and several time series data fields, voltage, current and temperature and some other fields that are irrelevant. There is also a field called numIntervals that contains the number of intervals in the time series data sets. The struct itself has only one element.

import numpy as np
from scipy.io import loadmat  # this is the SciPy module that loads mat-files
import matplotlib.pyplot as plt
from datetime import datetime, date, time
import pandas as pd

mat = loadmat('measured_data.mat')  # load mat-file
mdata = mat['measuredData']  # variable in mat file
mdtype = mdata.dtype  # dtypes of structures are "unsized objects"
# * SciPy reads in structures as structured NumPy arrays of dtype object
# * The size of the array is the size of the structure array, not the number
#   elements in any particular field. The shape defaults to 2-dimensional.
# * For convenience make a dictionary of the data using the names from dtypes
# * Since the structure has only one element, but is 2-D, index it at [0, 0]
ndata = {n: mdata[n][0, 0] for n in mdtype.names}
# Reconstruct the columns of the data table from just the time series
# Use the number of intervals to test if a field is a column or metadata
columns = [n for n, v in ndata.iteritems() if v.size == ndata['numIntervals']]
# now make a data frame, setting the time stamps as the index
df = pd.DataFrame(np.concatenate([ndata[c] for c in columns], axis=1),
                  index=[datetime(*ts) for ts in ndata['timestamps']],
                  columns=columns)

Thursday, April 3, 2014

My fears about MATLAB

Someone just sent me a funny email about funny MATLAB bugs. When I say "funny" I mean in the geeky-(in fact I didn't even get why they were so funny)-way. I probably was targeted for this funny email thread because I have suggested switching from MATLAB to Python, but I think my reasons for suggesting this switch have been misunderstood. It doesn't have anything to do with bugs or the quality of MATLAB software - IMHO MATLAB is outstanding. My complaint is more practical. I am afraid of the consequences of the facts that MATLAB is closed-source and TMW is privately held. I hope that this perspective is useful, however what I express below is my opinion and based on my experiences not necessarily on facts, so please forgive me if there are some inaccuracies.

Here are my fears about MATLAB enumerated, and why I suggest switching to Python:

  1. If MATLAB goes out of business, your code is useless, and they could decide to close shop any day, because they’re not publicly traded.
  2. You can’t use it without a license! In my case I have to VPN to work to use it, this makes me not want to work from home because using vpn is just a smidge slower and another hurdle to getting started and of course forget working on airplanes or anywhere where there’s no internet.
  3. The $$$ for the toolboxes is obscene! Especially considering they are repackaging what is already free in the public domain in C/C++, FORTRAN and Python. It’s a racket. Ostensibly you could argue that the money is for support, but there are similar paid support options for Python (Anaconda, Enthought, ActiveState, etc.) that are substantially cheaper, and rival MATLAB support options to varying degrees of success.
  4. MATLAB is not portable, unless of course you use the MATLAB compiler toolbox and one of its toolbox add-ons like MATLAB builder-NE, builder-JA or builder-XL. That right there floors me as a scam, you can’t port it to someone unless you buy not one but 2 extra $$$$$ toolboxes and they are by far the most expensive toolboxes! And that’s the way it is with everything they sell. EG parallel toolbox is useless without the extra distributed computing toolbox, both of which are $$$$$! And you pay per number of machines in the computing cluster. Back to portability. If you want to share your MATLAB code with someone they will have to purchase MATLAB to use it.
  5. There is not enough consideration for backwards compatibility. I believe that TMW tries to minimize backwards incompatibility, but they still do it anyway, and in their business model, where they only make money if you maintain your license, they have a strong incentive to introduce backwards incompatibility. Other languages have the opposite incentive, in order to maintain the code-base of external packages, libraries and toolboxes that would fail if backwards incompatibilities were introduced. IE you will never find backwards incompatibilities between any version of Python-2.7.x (or in between versions of Python-3.x.x, although Python-3 is not strictly backwards compatible with Python-2).
  6. It is very powerful, but it is not the most powerful coding platform out there. FORTRAN as ancient as it is, still exceeds MATLAB and the newer Julia is faster than them all! See the comparison chart where is says “High-Performance JIT Compiler”.

Other than these few issues, I revere MATLAB and have used it extensively for decades. I rarely have issues with it and it is clearly one of the best analysis tools for science and engineering, but it isn’t the only one and it’s debatable if it’s the best.

I adhere to the philosophy of "use the right tool for the right job" and that nothing is binary, even quanta come in different flavors.

Thursday, October 3, 2013

Turn off Objective-C for m-files, Turn on MATLAB

I just posted about how cool Sublime Text 2 editor is, in Markdown builder for Sublime Text 2, but it's not all ice cream and apple pie. One thing that's a drag is that it always chooses Objective-C syntax for MATLAB. It's a pretty quick fix. Opening up the MATLAB language file found under packages in the preferences folder there's this comment re: file type
 <key>fileTypes</key>
 <array>
  <!-- Actually, it's generally .m, but that's taken by Objective-C. It needs an entry to show up in the syntax list. -->
  <string>matlab</string>
 </array>
Look in the Objective-C language file and you see this is indeed true, m-files are treated as Objective-C instead of MATLAB.
 <key>fileTypes</key>
 <array>
  <string>m</string>
  <string>h</string>
 </array>
Cut and paste <string>m</string> from the Objective-C file to the MATLAB file, and viola, it's all ice cream and apple pie!

Monday, September 30, 2013

Are MATLAB containers.Map more efficient?

UPDATE 2015-02-10 I learned something interesting recently that sheds some light on the answer to this question. I believe that MATLAB's containers.Map is a wrapper around Java's java.util.HashMap. A hash map or hash table is a zeroth order look-up table that uses a hash of the look-up key or index for tables as the address in memory that contains the corresponding value. Therefore it doesn't matter how big the hash map or hash table is, MATLAB (or Java) can immediately return the contents given the key. Since the hash is guaranteed to be unique for any given index or key, the memory address of the value will also be unique. So the answer to the question, "Are MATLAB containers.Map more efficient?" is absolutely and without any doubt a loud and resounding, "Yes!" QED

MATLAB's containers.Map's are similar to a Java HashMap or a Python dictionary. They have been around at least since 2008b believe it or not. They were billed as
Fast Key Lookup Provided with New Map Data Structure
when they were introduced. See Programming Fundamentals in 2008b Release Notes. How much memory do they realy take up? MATLAB doesn't say. It seems like they're smaller, but you'll soon see that every containers.Map is always 112 Bytes. How much faster can they really be? My guess is they are really only more efficient for really large data, that are only nested with other containers.Map's of primitive types (IE integers, doubles, &c.).

They have some limitations in subassignment and indexing.

For example:
  • If the value of map('k1') is also a containers.Map,
  • map('k1')('k2')
    Error: ()-indexing must appear last in an index expression.
    then this is invalid because MATLAB only allows one pair of parentheses which must appear last. So you'll have to split this into two commands. This also allows assignment into the nested containers.Map ...
    val_is_map = map('k1') % make a temp handle to the top level containers.Map
    val_is_map('k2') = new_value % assignment using the handle also changes the containers.Map it points to
    test = map('k1') % make another handle to test the original containers.Map was updated
    test('k2') == new_value % true
    ... because containers.Map's are handles (IE pointers) so changing the value of a copied containers.Map changes the source.
  • If the value of map('k1') is a structure,
  • map('k1').field = 'foo'
    Error using containers.Map/subsasgn
    Only one level of indexing is supported by a containers.Map.
    then this is also not valid because only the top level of containers.Map can be assigned.
  • Finally if map('k1') is a cell array, then good luck trying to index it.
>> dict = containers.Map({'all','amend','author','msg'}, ...
       {{'-a','--all',true}, ...
       {[],'--amend',true}, ...
       {[],'--author',true}, ...
       {'-m','--message',false}})

dict = 

  Map with properties:

        Count: 4
      KeyType: char
    ValueType: any

>> s = struct('all',{'-a','--all',true}, ...
       'amend',{[],'--amend',true}, ...
       'author',{[],'--author',true}, ...
       'msg',{'-m','--message',false})

s = 

1x3 struct array with fields:

    all
    amend
    author
    msg

>> c1 = {{'all','-a','--all',true}, ...
       {'amend',[],'--amend',true}, ...
       {'author',[],'--author',false}, ...
       {'msg','-m','--message',false}}

c1 = 

    {1x4 cell}    {1x4 cell}    {1x4 cell}    {1x4 cell}

>> c2 = {'all','-a','--all',true; ...
       'amend',[],'--amend',true; ...
       'author',[],'--author',false; ...
       'msg','-m','--message',false}

c2 = 

    'all'       '-a'    '--all'        [1]
    'amend'       []    '--amend'      [1]
    'author'      []    '--author'     [0]
    'msg'       '-m'    '--message'    [0]

>> whos
  Name      Size            Bytes  Class

  dict      4x1               112  containers.Map
  s         1x3              1670  struct
  c1        1x4              2344  cell
  c2        4x4              1896  cell

Sunday, September 29, 2013

MATLAB syntax for Java inner objects

MATLAB is a Java (and .NET) interpreter, yay!
using-java-libraries-in-matlab
But calling inner objects can be tricky in MATLAB. Use the `javaMethod` and `javaObject` builtins. All the examples are from org.eclipse.jgit
javamethod
javaobject

Constants

These are the easiest of all. Though not technically an inner anything, a constant could be confusing, but it is called exactly as it would be in Java or MATLAB.
    filesystem = org.eclipse.jgit.util.FS.DETECTED
FS is a the filesystem class in org.eclipse.jgit.util pacakge. Its constant DETECTED can be accessed using regular dot notation.
org/eclipse/jgit/util/FS

Enumeration of an inner class

This is where it starts to get tricky. A nested or inner class is created in a separate class file preceded with a dollar sign. MATLAB uses the same notation, but only as a string in the javaMethod command.
    NOTRACK = javaMethod('valueOf', ...
        'org.eclipse.jgit.api.CreateBranchCommand$SetupUpstreamMode', ...
        'NOTRACK')
The `CreateBranchCommand has a nested class called `SetupUpstreamMode`. Access it in MATLAB with a dollar symbol, "$", instead of dot notation, but access it using `javaMethod`. For example it has several enumerations. `NOTRACK` is an enumeration of `SetupUpstreamMode`. Calling the `valueOf()` method of `SetupUpstreamMode` and passing it the string, "NOTRACK" inside the MATLAB builtin `javaMethod` does the trick.
org/eclipse/jgit/api/CreateBranchCommand
org/eclipse/jgit/api/CreateBranchCommand.SetupUpstreamMode
org/eclipse/jgit/api/CreateBranchCommand.SetupUpstreamMode.html#NOTRACK

Construct an inner class object

This is also easy.
    user = javaObject('org.eclipse.jgit.transport.CredentialItem$Username')
Username is an static nested class of CredentialItem. Access it using the dollar sign instead of dot notation in a call to `javaObject`.
org/eclipse/jgit/transport/CredentialItem.Username

And that's pretty much that. There are some other Java tools, like javaArray, javaMethodEDT & javaObjectEDT. I'll update this more later. Promise.

Credit for MATLAB brush: Will Schleter. Thanks!

Friday, September 20, 2013

IPOPT as non-linear solver for MATLAB

You have a non-linear problem to solve but not the MATLAB Optimization Toolbox?
  1. First download the IPOPT mex and m-files, and extract to your MATLAB search path.
  2. Make an m-file that defines your objective and constraints, gradient and Jacobian.
  3. Credit for MATLAB brush: Will Schleter. Thanks!
  4. Other non-linear solvers for MATLAB
  5. Perfect for solving a staggered mesh.
  6. If you were using Python you could use optimization routines in SciPy.
function [x,info] = myNonLinearProblem(x0, auxdata)
%MYNONLINEARPROBLEM Solves my non-linear problem
% [X,INFO] = MYNONLINEARPROBLEM[X0,AUXDATA]
% returns solution, X, and INFO to my non-linear problem
% X0 is the initial guess
% AUXDATA are any additional arguments my non-linear problem
% requires

x0 = x0(:); % initial guess

%% constraints
%set all of your equations as constraints
funcs.constraints = @constraints;
% constraints require a Jacobian
funcs.jacobian = @jacobian;
% Jacobians require a sparsity structure
funcs.jacobianstructure = @jacobianstructure;
% set upper and lower bounds of constraints to zero
options.cl = zeros(size(x0)); % lower bounds
options.cu = zeros(size(x0)); % lower bounds

%% objective
% set the objective sum of the squares
funcs.objective = @objective;
% objective requires a gradient
funcs.gradient = @gradient;

%% options
% set Quasi-Newton option
options.ipopt.hessian_approximation = 'limited-memory';

%% solve
[x,info] = ipopt_auxdata(x0,funcs,options);
end

% x & auxdata must be passed as only args to
% objective, gradient, constraints and jacobian

function f = objective(x,auxdata)
% objective is the sum of the squares of the residuals
f = residual(x,auxdata);
f = f(:);
f = f'*f;
end

function g = gradient(x,auxdata)
[f,j] = residual(x,auxdata);
f = f(:);
g = f'*j;
end

function f = constraints(x,auxdata)
f = residual(x,auxdata);
f = f(:);
end

% Jacobian and Jacobian structure must be sparse

function j = jacobian(x,auxdata)
% rows correspond to each constraint
% columns correspond to each x
[~,j] = residual(x,auxdata);
j = sparse(j);
end

function j = jacobianstructure(x)
% x is the only arg passed to Jacobian structure
% assuming closed system of equations
% # of constraints = degrees of freedom
% therefore Jacobian matrix will be square
j = sparse(ones(size(x)));
end

% put the equations and their derivatives here
% unfortunately IPOPT is not a Jacobianless solver :(

function [f,j] = residuals(x,auxdata)
% calculate your residuals here
% f1(x,auxdata) = lhs1(x,auxdata) - rhs1(x,auxdata) = 0
% f2 = ...
% j1(x,auxdata) = [df1/dx1, df1/dx2, ...]
% j2 = ...
end

Wednesday, August 14, 2013

Flatten nested if statements with the opposite condition

Have you ever found yourself nesting if, for and other flow-control statements seemingly endlessly into the dreaded arrow formation?
EG:
if this:
    if that:
        for x in X:
            if yuck:
                ...
            else:
                ...
                continue
    else:
        while Y:
            if foobar:
                ...
            else:
                ...
                break
else:
    ...
One of the easiest ways to collapse if statements is using the opposite condition and return, continue or break.
EG:
if not this:
    ...
    return
if not that:
    while Y:
        if not foobar:
            ...
            break
        ...
    return
for x in X:
    if not yuck:
        ...
        continue
    ...
Some refactoring tools will help you do this, but it good programming practice to avoid nested flow-control statements when possible. Even though in this case it only eliminated 2 lines, it is more compact, lines are not as long, so wrapping/continuing/splitting commands is not an issue, and in general the code should run faster, since it only executes as much code as is needed before returning, continuing or breaking.

Saturday, June 15, 2013

[Python] read formatted input

I have come to the same conclusion as this blog and this "physics forum thread" (is this a real forum? or a copy of another forum?).
There is no Python equivalent of C/C++ fscanf or MATLAB fscanf, sscanf or textscan.
Here are some alternatives that I have found.
  1. numpy.genfromtext() does more or less exactly the same thing. It reads strings, via StringIO, and file. There is a nice section on importing data in the NumPyUser Guide.
    • instead of format specifiers like '%8f%4s%2d' use delimiter=(8, 4, 2) and set dtype=(float, str, int). Voila!
    • But genfromtext() does so much more! Using dtypes you can also set field names. There are options for skipping headers and footers, See the documentation.
  2. parse 1.6.1 offers parse(), the opposite of format() on PyPI. I haven't tried it, and I wish there was more documentation, specifically examples of multiple parsed tokens, but it does seem to be a python version of textscan, but for strings only.
  3. The re module in the standard Python reference is an obvious choice to parse tokens from strings. There is even a section on simulating scanf that offers recipes for %f and other formatters.
  4. For simple delimiters, one can use either of the following:
    • csv module from the standard Python reference
    • numpy.loadtxt() which has the added advantage of reading in data as NumPy arrays.
    • str.split() obviously
There are probably many other methods, but for MATLAB converts, once they move from disbelief and denial onto acceptance, it's pretty straightforward issue to resolve.

Thursday, May 23, 2013

MATLAB/Python SQL

The players:

MATLAB

  1. MySQL Database Connector [2005-10-10] by Robert Almgren on FEX with additional information at his site at the NYU Courant Institute of Math Sciences.
  2. MySQL Connector: mYm [v1.36 2010-05-19] by Yannick Maret with many additional files by Dimitri Shvorob
    Access a MySQL database
    A Powerful Sidekick: Using MySQL for High-Volume Data Manipulation in Matlab
    MySQL shortcut files by Carrie Wall
  3. queryMySQL [2012-06-22] by Jonathan Karr
  4. Myblob [2006-01-09] by Joerg Buchholz
  5. java.sql why not use native Java? Always the right solution with MATLAB right?
  6. .NET SqlConnection class
Python

Saturday, April 27, 2013

Sphinx domains for MATLAB

[UPDATE 2013-06-20] sphinxcontrib-matlabdomain is now at the cheese factory, so you should be able to install it using Pip or easy_install, or download the and unzip the source and use

>>> python setup.py install

Sphinx is a Python module that generates beautiful documentation using ReStructuredText. It is extensible to other "domains" other than Python. I've made a MATLAB domain that you can install on Bitbucket. Fork or clone it.

To use it you must have Sphinx and its dependencies. Then install the matlabdomain by cloning my fork of the sphinx-contrib repository from Bitbucket. Then run `python setup.py install` from inside the `matlabdomain` directory. If you run `pip freeze` you sill see it listed but there is a warning that the `dependency_links` are not in an svn repository - this is a known bug. After you've run sphinx-quickstart, edit conf.py to include `sphinxcontrib.matlab` in the list of `extensions` and also add the following line:

primary_domain = 'mat'

Voila! You can now document MATLAB in Sphinx, as in the example above. Do note the TODO in matlab.py - I have not added autodocs for MATLAB. It wouldn't make sense anyway, since MATLAB function and class definitions do not use ReStructuredText markup for their H1 and help comment lines.

Sphinx matlabdomain

I wrote a post on installing Sphinx with latex support. Also you will need a working make binary.

Old still shots of demo from before I added the iframe:

Tuesday, April 16, 2013

JGit & MATLAB Matrimony

MATLAB is a Java interpreter. See Java Libraries in MATLAB help. Now it just so happens that there is an excellent Java implementation of Git, the most widely used distributed version control system, called JGit. So it seems obvious that the best way to use Git in MATLAB is with JGit, and it turns out this is surprisingly easy, because JGit has a porcelain class.



I have written a ridiculous wrapper to use JGit in MATLAB that you can clone from Github or download from the MATLAB Central File Exchange. Try my wrapper, but then either contribute or branch out and just use the JGit package. It is surprisingly easy.

NOTE: Did I mention that you do not need to install anything! JGit is your Git client. JGit is not a wrapper for C/C++/Perl scripts. It is a pure Java implementation of Git. That really makes this the one of the easiest way to use Git if you are also using MATLAB.

Enjoy!

Wednesday, March 13, 2013

Horner's method in 2D

Horner's method is a fast way to make polynomials that removes unnecessary and costly evaluation of power's. It's easy to do for 1-D polynomials, and also pretty easy to do for 2-D polynomials.

The format of p, the polynomial coefficients, is similar to 1-D polynomials:
\[\begin{aligned} f\left(x,y\right)=&p_1 x^n y^m+p_2 x^{\left(n-1\right)} y^m+\ldots+p_{n+1} y^m+\ldots \\ &p_{n+2}x^ny^{\left(m-1\right)}+p_{n+3}x^{\left(n-1\right)}y^{\left(m-1\right)}+\ldots+p_{2\left(n+1\right)}y^{\left(m-1\right)}+\ldots \\ &\ldots \\ &p_{m\left(n+1\right)+1}*x^n+p_{m\left(n+1\right)+2}*x^{\left(n-1\right)}+\ldots+p_{\left(n+1\right)\left(m+1\right)} \end{aligned} \]

Gists:

BTW the double nested loop here is about 25% faster than 2 smaller loops with a lot of vectorization. Not sure why, but I occasionally find that loops are actually more efficient than big matrix calculations.

Wednesday, December 5, 2012

Download sites for old, free MS compilers and IDEs

[UPDATE 2015-03-13] I do not recommend installing VS2010 Express (or Professional). This program is very difficult to remove and has become obsolete, with VS2013. If you are stuck with this on your computer you may be able to remove it by following these steps.
  1. Make sure you have copies of the VS2010 SP1 installer. The web installer is fine, but the iso may come in useful. Don't bother creating a manual system restore point. Even when you roll back changes, the issues that cause the majority of problems are not resolved. However I guess it can't hurt either. If you really want to cover your bases, the best thing would be to make a recovery disk and an disk image. This way you can roll back changes if they go awry.
  2. If you have installed VS2010 SP1, you must remove this first. You should be able to remove it from add/remove programs in the control panel. If not try
    • C:\ProgramData\VS\vs2010sp1\SetupCache\setup.exe /uninstall /force
    • Download the installer and run VS10sp1-KB983509.exe /uninstall /force
    • Download and extract the iso image and run setup.exe /uninstall /force
    • Reinstall SP1 and then try uninstalling it from add/remove programs in control panel. You may need to reinstall VS2010 VC10 or VCS10 before SP1.
  3. Remove VS2010 Tools for Office Runtime and VS2010 ADO.NET Entity Framework. You may need to remove these before SP1.
  4. Use the VS2010 uninstall utility documented first here then later here. Make sure you use the options in the post /full to remove everything!
Note this took many iterations to actually get all of VS2010 off of my system, so be prepared for frustration and irritation, but persevere and it can be done. Just make sure you have copies of the installer so that you can reinstall and try to remove everything in the correct order again! You may have an issue removing or reinstalling Windows SDKs. If so see Upgrading to Visual Studio 2013.

[UPDATE 2014-11-13] Free x86 and AMD64 (x86-64) VC90 c-compilers for Python-2.7 are now available from Microsoft. The free VC90 compilers can be used to install package source that contains c-extensions using either pip, setuptools or distutils. For example, pip install dulwich will build and install the Python Git implementation which contains several speedups as c-extensions.

[UPDATE 2013-10-03, 2014-04-16] Sad to report that clicking on #1 MS Visual Studio 2008 Express states that it has been retired. Oh, yes! VS2008 Express didn't allow targeting x64 platforms, without some serious hoop-jumping, but VS2010 Express does, and VS2010 also lets you select the V90 toolset, so building shared objects for Python-2.7 is no problem. Also, SDK7 has the exact same compilers as V90, and it is still supported so they are more current. Ditto for SDK7.1 & V100. Oh no! Does this mean we finally have to switch to Python 3? If you really want VS2008, the web installer does however still work. Grab it from my dropbox.

  1. Microsoft Visual Studio 2008 Express Editions with SP1: This one is necessary for python 2.7.3 extensions. You can't get it from the Visual Studio page anymore, now that they've moved on to 2012, but download links for vcsetup.exe which install MSVC90 Express are in the Microsoft Download Center, as are vcssetup (C#), vbsetup.exe (vbs) and vwsetup.exe (web). You also get the opportunity to install SQL Server 2008 and Silverlight SDK. Visual Studio 2008 Express has been discontinued, and is obsolete because Visual Studio 2010 Express includes the V90 toolset. See update note at top of page. Not sure if Visual Studio 2008 SP1 download will install for free, but it may. VS2008 is not required to build Python-2.7 extensions, instead use SDK7 which replaces the v90 compilers.
  2. Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1: You cannot build 64-bit applications with the free version of VC90 unless you have Windows SDK 7. Note this *not* 7.1, which is VC100, also note that .NET Framework 3.5 is part of Windows 7, so you don't have to download it separately, and of course make sure that you get all updates before installing. Specifically you must have SP1. The paths in vcvarsall.bat are incorrect, you will need to fix them to use pip with v90. Otherwise use sdk7 shell and follow the directions in the post on installing Python x64 extensions with pip
  3. Visual Studio 2010 Express is still available from the main VS site. They have 2012 and 2010, and all of the flavors.
  4. Microsoft SDK 7.1 has some issues with VC100. Basically you should follow this procedures:
    1. Visual Studio 2010 RTM
    2. Windows SDK 7.1
    3. Visual Studio 2010 SP1
    4. Visual C++ 2010 SP1 Compiler Update for the Windows SDK 7.1
    See these posts:
    Setup & Install by Heath Stewart
    Visual C++ Team Blog
    FIX: Visual C++ compilers are removed ...
  5. Microsoft Windows SDK for Windows 7 and .NET Framework 4
  6. Beware here, you might run into this error, which is very confusing, the installer quits with the message "Installation of the “Microsoft Windows SDKfor Windows 7” product has reported the following error: Please refer to Samples\Setup\HTML\ConfigDetails.htm document for further information." Totally useless, but further examination of the log file or googling around you might see the real source of the error, it's not SP1 but the redistributable that is too new: "C:\Program Files\Microsoft SDKs\Windows\v7.1\Setup\SFX\vcredist_x64.exe installation failed with return code 5100". The solution is to remove the redistributables and then reinstall them later. See this knowledge base article:
    Windows SDK Fails to Install with Return Code 5100
  7. Upgrade to Microsoft Visual Studio 2010 SP1. See this link for what's in SP1.
    Description of Visual Studio 2010 Service Pack 1
  8. Download the update after you follow the procedures here:
    Microsoft Visual C++ 2010 Service Pack 1 Compiler Update for the Windows SDK 7.1


Wednesday, August 22, 2012

Use deep copy to make cheap copies of objects

MATLAB

There is a feature in MATLAB called "cheap copies" that makes expanding an array of different objects of the same class a snap. When I say different objects I mean that in the case of handle class objects, each object references a unique object, so that a change in one of its properties affects only it, and is not simultaneously changed in all of the other objects. That's what would happen if all of the objects were really references to the exact same object.

For example assume you have the following MATLAB handle class.
classdef MyClass < handle
    properties
        a
    end
    methods
        function obj = MyClass(a)
            obj.a = a;
        end
    end
end
Then ...
myClassArray(3) = MyClass(5)
...creates an array of three MyClass objects which are unique.

Python

In Python the way to do this is with deepcopy from the builtin copy package.

For example assume you have the following Python class.
from copy import deepcopy

class MyClass(object):
    def __init__(self, a=5):
        self.a = a

# make 3 copies, but all point to the same instance

myClassArray = [MyClass(a=5)] * 3

# now make deep copies of each object in the array except the first
# one, so that they are now all unique instances

myClassArray[1:] = [deepcopy(dummy) for dummy in myClassArray[1:]]
Enjoy! For objects that are computationally expensive, this is a very fast way to build a bunch of identical but unique "copies" of objects of the same class.
Fork me on GitHub