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.
“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
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.
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?
Remove Visual Studio 2010 SP1 and run the uninstall utility
Name
Size
Version
Microsoft Visual Studio 2010 Service Pack 1
75.9 MB
10.0.40219
Microsoft Visual C++ 2010 Express - ENU
10.0.40219
Microsoft Visual C# 2010 Express - ENU
10.0.40219
Microsoft Visual Studio 2010 Express Prerequisites x64 - ENU
21.6 MB
10.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.
Remove Visual Studio 2008 SP1.
Name
Size
Version
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.
Remove both SDKs for Windows 7 and .NET Frameworks 3.5 and 4.0
Name
Size
Version
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.
Remove everything else
Name
Size
Version
Microsoft Document Explorer 2008
Microsoft Help Viewer 1.1
3.97 MB
1.1.40219
Microsoft SQL Server 2008 R2 Management Objects
12.4 MB
10.50.1750.9
Microsoft SQL Server Compact 3.5 SP2 ENU
3.39 MB
3.5.8080.0
Microsoft SQL Server Compact 3.5 SP2 x64 ENU
4.50 MB
3.5.8080.0
Microsoft SQL Server System CLR Types
930 KB
10.50.1750.9
Application Verifier (x64)
55.3 MB
4.1.1078
Debugging Tools for Windows (x64)
39.8 MB
6.12.2.633
Microsoft Visual Studio 2008 Remote Debugger light (x64) - ENU
Microsoft Visual Studio 2010 ADO.NET Entity Framework Tools
34.2 MB
10.0.40219
Microsoft Visual Studio 2010 Tools for Office Runtime (x64)
10.0.50903
Microsoft Windows Performance Toolkit
26.1 MB
4.8.0
Microsoft Windows SDK for Visual Studio 2008 Headers and Libraries
114 MB
6.1.5288.17011
Microsoft Windows SDK for Visual Studio 2008 SP1 Express Tools for .NET Framework - enu
4.41 MB
3.5.30729
Microsoft Windows SDK for Visual Studio 2008 SP1 Express Tools for Win32
2.61 MB
6.1.5295.17011
As you can see there is a lot of detritus left behind.
Remove the 2008 & 2010 C++ compilers and the Visual C++ 2010 SP1 redistributables.
Name
Size
Version
Microsoft Visual C++ Compilers 2008 Standard Edition - enu - x64
127 MB
9.0.30729
Microsoft Visual C++ Compilers 2008 Standard Edition - enu - x86
321 MB
9.0.30729
Microsoft Visual C++ Compilers 2010 SP1 Standard - x64
206 MB
10.0.40219
Microsoft Visual C++ Compilers 2010 SP1 Standard - x86
613 MB
10.0.40219
Microsoft Visual C++ 2010 x64 Redistributable - 10.0.40219
6.86 MB
10.0.40219
Microsoft Visual C++ 2010 x86 Redistributable - 10.0.40219
5.44 MB
10.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.
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.
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.
% 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
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
Construct a units registry, which contains all units, constants, prefixes and dimensions.
>> ureg = Quantities.unitRegistry
ureg =
Map with properties:
Count: 279
KeyType: char
ValueType: any
Optionally pass verbosity parameter to unitRegistry to see list of units loaded.
>> ureg = Quantities.unitRegistry('v',2)
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.
>> 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];
Perform operations. All units are converted to base.
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.
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
Start memcached server
C:\> C:\path\to\memcached.exe -vv
Do this on both MATLAB instances
>> 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()
MATLAB instance #1
>> mc.Set('name','mark')
1
MATLAB instance #2
>> 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.
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.
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.
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.
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.
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.
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)
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:
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.
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.
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.
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.
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).
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.
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.
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
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.
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.
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
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.
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.
parse 1.6.1 offersparse(), 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.
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.
For simple delimiters, one can use either of the following:
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.
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.
MATLAB is a Javainterpreter. 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.
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.
[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.
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.
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
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.
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.
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
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.