New package QuantEcon.jl.
This package collects code for quantitative economic modeling. It is currently comprised of two main parts:
A toolbox of routines useful when doing economics
Implementations of types and solution methods for common economic models.
This library has a python twin: QuantEcon.py. The same development team is working on both projects, so we hope to keep the two libraries in sync very closely as new functionality is added.
The library contains all the code necessary to do the computations found on http://quant-econ.net/, a website dedicated to providing lectures that each economics and programming. The website currently (as of 9/18/14) has only a python version, but the Julia version is in late stages of refinement and should be live very soon (hopefully within a week).
The initial version of the website will feature 6 lectures dedicated to helping a new user set up a working Julia environment and learn the basics of the language. In addition to this language specific section, the website will include 22 other lectures on topics including
All the lectures have code examples in Julia and most of the 22 will display code from the QuantEcon.jl library.
New package QuantEcon.jl.
This package collects code for quantitative economic modeling. It is currently comprised of two main parts:
A toolbox of routines useful when doing economics
Implementations of types and solution methods for common economic models.
This library has a python twin: QuantEcon.py. The same development team is working on both projects, so we hope to keep the two libraries in sync very closely as new functionality is added.
This is fantastic!
Any experiences/opinions/pitfalls your group discovered on the Python vs Julia question? I guess you pretty much implemented the same algorithms in both languages. Did you find one is faster than the other? Were there major areas where Julia lagged behind Python?
Thanks,
David
From: julia...@googlegroups.com [mailto:julia...@googlegroups.com] On Behalf Of Spencer Lyon
Sent: Thursday, September 18, 2014 7:14 PM
To: julia...@googlegroups.com
Subject: [julia-users] ANN: QuantEcon.jl
New package QuantEcon.jl.
This package collects code for quantitative economic modeling. It is currently comprised of two main parts:
1. A toolbox of routines useful when doing economics
2. Implementations of types and solution methods for common economic models.
Hi David,
Thanks for the questions, I’ll respond in chunks.
Any experiences/opinions/pitfalls your group discovered on the Python vs Julia question?
I personally love both languages and use both regularly. I find myself reaching for Julia for most things right now — I love the more advanced features like metaprogramming and parallel processing that are either non-existent or not as well integrated into the python language itself (I know there are many packages that provide similar features for python, but they don’t feel as natural as they do in Julia).
Did you find one is faster than the other?
As you might expect, we found that Julia was faster than Python for most things. This is probably an artifact of the type of algorithms we used. Often we would define an operator that loops over a grid, and then iterate on that operator until we find a fixed point. Because of this looping, Julia has a predictable speed advantage.
Were there major areas where Julia lagged behind Python?
I can think of two places where performance in Julia wasn’t as good as performance in python:
quadgk routine was much slower scipy.integrate.fixed_quad. This is not a fair comparison because the algorithms employed by the two functions are very different. Specifically quadgk uses an adaptive algorithm while fixed_quad just uses standard Gaussian quadrature. To get around this we actually implemented a whole suite of quadrature routines in the file quad.jl. After switching the Julia code from using quadgk to our own internal quadrature methods, we got approximately the same solutions, but the code was between 35-115 faster. numpy.interp does simple piecewise linear interpolation. We ended up using the CoordInterpGrid type from Grid.jl to accomplish this. As of right now the interpolation steps are the biggest bottleneck in most of the functions we have.We also didn’t really find that Julia was lagging behind Python in terms of libraries that we needed. All the functionality we needed was already available to us. We are using PyPlot.jl to generate graphics, so I guess the some of the Julia code is dependent on Python. Come to think of it the one thing we would like to have that we haven’t been able to find is arbitrary precision linear algebra. In Python this can be achieved through SymPy’s wrapping of mpmath, but as far as I know we don’t yet have arbitrary precision linear algebra in Julia.
Hey Jameson,
Thanks for the tip, but I don’t think we have “most linear algebra operations” defined on BigFloat types. See the example below (on Julia master, one day old):
julia> P1
3x3 Array{Float64,2}:
1.0 0.0 0.0
0.2 0.5 0.3
0.0 0.0 1.0
julia> big_P1 = big(P1)
3x3 Array{BigFloat,2}:
1e+00 … 0e+00
2.00000000000000011102230246251565404236316680908203125e-01 2.99999999999999988897769753748434595763683319091796875e-01
0e+00 1e+00
julia> eig(P1)
([0.5,1.0,1.0],
3x3 Array{Float64,2}:
0.0 0.928477 0.0
1.0 0.371391 0.514496
0.0 0.0 0.857493)
julia> eig(big_P1)
ERROR: `eigfact!` has no method matching eigfact!(::Array{BigFloat,2})
in eigfact at linalg/factorization.jl:451
...<div title="MDH:SGV5IEphbWVzb24sPGRpdj48YnI+PC9kaXY+PGRpdj5UaGFua3MgZm9yIHRoZSB0aXAsIGJ1dCBJ IGRvbid0IHRoaW5rIHdlIGhhdmUgIm1vc3QgbGluZWFyIGFsZ2VicmEgb3BlcmF0aW9ucyIgZGVm aW5lZCBvbiBgQmlnRmxvYXRgIHR5cGVzLiBTZWUgdGhlIGV4YW1wbGUgYmVsb3cgKG9uIEp1bGlh IG1hc3Rlciwgb25lIGRheSBvbGQpOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+YGBgPC9kaXY+ PGRpdj48ZGl2Pmp1bGlhJmd0OyBQMTwvZGl2PjxkaXY+M3gzIEFycmF5e0Zsb2F0NjQsMn06PC9k aXY+PGRpdj4mbmJzcDsxLjAgJm5ic3A7MC4wICZuYnNwOzAuMDwvZGl2PjxkaXY+Jm5ic3A7MC4y ICZuYnNwOzAuNSAmbmJzcDswLjM8L2Rpdj48ZGl2PiZuYnNwOzAuMCAmbmJzcDswLjAgJm5ic3A7 MS4wPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5qdWxpYSZndDsgYmlnX1AxID0gYmlnKFAxKTwv ZGl2PjxkaXY+M3gzIEFycmF5e0JpZ0Zsb2F0LDJ9OjwvZGl2PjxkaXY+Jm5ic3A7MWUrMDAgJm5i c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7 ICZuYnNwOyAmbmJzcDsgJm5ic3A74oCmICZuYnNwOzBlKzAwPC9kaXY+PGRpdj4mbmJzcDsyLjAw MDAwMDAwMDAwMDAwMDExMTAyMjMwMjQ2MjUxNTY1NDA0MjM2MzE2NjgwOTA4MjAzMTI1ZS0wMSAm bmJzcDsgJm5ic3A7IDIuOTk5OTk5OTk5OTk5OTk5ODg4OTc3Njk3NTM3NDg0MzQ1OTU3NjM2ODMz MTkwOTE3OTY4NzVlLTAxPC9kaXY+PGRpdj4mbmJzcDswZSswMCAmbmJzcDsgJm5ic3A7ICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7 ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm bmJzcDsgJm5ic3A7IDFlKzAwPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5qdWxpYSZndDsgZWln KFAxKTwvZGl2PjxkaXY+KFswLjUsMS4wLDEuMF0sPC9kaXY+PGRpdj4zeDMgQXJyYXl7RmxvYXQ2 NCwyfTo8L2Rpdj48ZGl2PiZuYnNwOzAuMCAmbmJzcDswLjkyODQ3NyAmbmJzcDswLjA8L2Rpdj48 ZGl2PiZuYnNwOzEuMCAmbmJzcDswLjM3MTM5MSAmbmJzcDswLjUxNDQ5NjwvZGl2PjxkaXY+Jm5i c3A7MC4wICZuYnNwOzAuMCAmbmJzcDsgJm5ic3A7ICZuYnNwOyAwLjg1NzQ5Myk8L2Rpdj48ZGl2 Pjxicj48L2Rpdj48ZGl2Pmp1bGlhJmd0OyBlaWcoYmlnX1AxKTwvZGl2PjxkaXY+RVJST1I6IGBl aWdmYWN0IWAgaGFzIG5vIG1ldGhvZCBtYXRjaGluZyBlaWdmYWN0ISg6OkFycmF5e0JpZ0Zsb2F0 LDJ9KTwvZGl2PjxkaXY+Jm5ic3A7aW4gZWlnZmFjdCBhdCBsaW5hbGcvZmFjdG9yaXphdGlvbi5q bDo0NTE8L2Rpdj48ZGl2PmBgYDwvZGl2Pjxicj5PbiBGcmlkYXksIFNlcHRlbWJlciAxOSwgMjAx NCA4OjI3OjUwIFBNIFVUQy00LCBKYW1lc29uIHdyb3RlOjxibG9ja3F1b3RlIGNsYXNzPSJnbWFp bF9xdW90ZSIgc3R5bGU9Im1hcmdpbjogMDttYXJnaW4tbGVmdDogMC44ZXg7Ym9yZGVyLWxlZnQ6 IDFweCAjY2NjIHNvbGlkO3BhZGRpbmctbGVmdDogMWV4OyI+PGRpdiBkaXI9Imx0ciI+PHNwYW4g c3R5bGU9ImZvbnQtZmFtaWx5OmFyaWFsLHNhbnMtc2VyaWY7Zm9udC1zaXplOjEzcHgiPiZndDsg YXJiaXRyYXJ5IHByZWNpc2lvbiBsaW5lYXIgYWxnZWJyYTwvc3Bhbj48YnI+PGRpdj48c3BhbiBz dHlsZT0iZm9udC1mYW1pbHk6YXJpYWwsc2Fucy1zZXJpZjtmb250LXNpemU6MTNweCI+PGJyPjwv c3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxlPSJmb250LWZhbWlseTphcmlhbCxzYW5zLXNlcmlm O2ZvbnQtc2l6ZToxM3B4Ij5pIHRoaW5rIG1vc3QgbGluZWFyIGFsZ2VicmEgb3BlcmF0aW9ucyBh cmUgZGVmaW5lZCBpbiBqdWxpYSBhbmQgdGh1cyB3aWxsIHdvcmsgZm9yIGJpZ251bXMuIHN0aWNr aW5nIGEgY2FsbCB0byBiaWcoKSBzb21ld2hlcmUgaW4gdGhlIGNvZGUgaXMgdXN1YWxseSBlbm91 Z2ggdG8gcHJvbW90ZSBldmVyeXRoaW5nPC9zcGFuPjwvZGl2PjxkaXY+PGJyPjxkaXYgY2xhc3M9 ImdtYWlsX3F1b3RlIj5PbiBGcmksIFNlcCAxOSwgMjAxNCBhdCA4OjA2IFBNLCBTcGVuY2VyIEx5 b24gPHNwYW4gZGlyPSJsdHIiPiZsdDs8YSBocmVmPSJqYXZhc2NyaXB0OiIgdGFyZ2V0PSJfYmxh bmsiIGdkZi1vYmZ1c2NhdGVkLW1haWx0bz0idGEwSm96Z1F2UHNKIiBvbm1vdXNlZG93bj0idGhp cy5ocmVmPSdqYXZhc2NyaXB0Oic7cmV0dXJuIHRydWU7IiBvbmNsaWNrPSJ0aGlzLmhyZWY9J2ph dmFzY3JpcHQ6JztyZXR1cm4gdHJ1ZTsiPnNwZW5jZS4uLkBnbWFpbC5jb208L2E+Jmd0Ozwvc3Bh bj4gd3JvdGU6PGJyPjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdp bjowIDAgMCAuOGV4O2JvcmRlci1sZWZ0OjFweCAjY2NjIHNvbGlkO3BhZGRpbmctbGVmdDoxZXgi PjxkaXYgZGlyPSJsdHIiPjxkaXY+PHAgc3R5bGU9Im1hcmdpbjoxLjJlbSAwcHghaW1wb3J0YW50 Ij5IaSBEYXZpZCw8L3A+CjxwIHN0eWxlPSJtYXJnaW46MS4yZW0gMHB4IWltcG9ydGFudCI+VGhh bmtzIGZvciB0aGUgcXVlc3Rpb25zLCBJ4oCZbGwgcmVzcG9uZCBpbiBjaHVua3MuPC9wPjxzcGFu Pgo8YmxvY2txdW90ZSBzdHlsZT0ibWFyZ2luOjEuMmVtIDBweDtib3JkZXItbGVmdC13aWR0aDo0 cHg7Ym9yZGVyLWxlZnQtc3R5bGU6c29saWQ7Ym9yZGVyLWxlZnQtY29sb3I6cmdiKDIyMSwyMjEs MjIxKTtwYWRkaW5nOjBweCAxZW07Y29sb3I6cmdiKDExOSwxMTksMTE5KTtxdW90ZXM6bm9uZSI+ CjxwIHN0eWxlPSJtYXJnaW46MS4yZW0gMHB4IWltcG9ydGFudCI+QW55IGV4cGVyaWVuY2VzL29w aW5pb25zL3BpdGZhbGxzIHlvdXIgZ3JvdXAgZGlzY292ZXJlZCBvbiB0aGUgUHl0aG9uIHZzIEp1 bGlhIHF1ZXN0aW9uPyA8L3A+CjwvYmxvY2txdW90ZT4KPC9zcGFuPjxwIHN0eWxlPSJtYXJnaW46 MS4yZW0gMHB4IWltcG9ydGFudCI+SSBwZXJzb25hbGx5IGxvdmUgYm90aCBsYW5ndWFnZXMgYW5k IHVzZSBib3RoIHJlZ3VsYXJseS4gSSBmaW5kIG15c2VsZiByZWFjaGluZyBmb3IgSnVsaWEgZm9y IG1vc3QgdGhpbmdzIHJpZ2h0IG5vdyDigJQgSSBsb3ZlIHRoZSBtb3JlIGFkdmFuY2VkIGZlYXR1 cmVzIGxpa2UgbWV0YXByb2dyYW1taW5nIGFuZCBwYXJhbGxlbCBwcm9jZXNzaW5nIHRoYXQgYXJl IGVpdGhlciBub24tZXhpc3RlbnQgb3Igbm90IGFzIHdlbGwgaW50ZWdyYXRlZCBpbnRvIHRoZSBw eXRob24gbGFuZ3VhZ2UgaXRzZWxmIChJIGtub3cgdGhlcmUgYXJlIG1hbnkgcGFja2FnZXMgdGhh dCBwcm92aWRlIHNpbWlsYXIgZmVhdHVyZXMgZm9yIHB5dGhvbiwgYnV0IHRoZXkgZG9u4oCZdCBm ZWVsIGFzIG5hdHVyYWwgYXMgdGhleSBkbyBpbiBKdWxpYSkuPC9wPjxzcGFuPgo8YmxvY2txdW90 ZSBzdHlsZT0ibWFyZ2luOjEuMmVtIDBweDtib3JkZXItbGVmdC13aWR0aDo0cHg7Ym9yZGVyLWxl ZnQtc3R5bGU6c29saWQ7Ym9yZGVyLWxlZnQtY29sb3I6cmdiKDIyMSwyMjEsMjIxKTtwYWRkaW5n OjBweCAxZW07Y29sb3I6cmdiKDExOSwxMTksMTE5KTtxdW90ZXM6bm9uZSI+CjxwIHN0eWxlPSJt YXJnaW46MS4yZW0gMHB4IWltcG9ydGFudCI+RGlkIHlvdSBmaW5kIG9uZSBpcyBmYXN0ZXIgdGhh biB0aGUgb3RoZXI/PC9wPgo8L2Jsb2NrcXVvdGU+Cjwvc3Bhbj48cCBzdHlsZT0ibWFyZ2luOjEu MmVtIDBweCFpbXBvcnRhbnQiPkFzIHlvdSBtaWdodCBleHBlY3QsIHdlIGZvdW5kIHRoYXQgSnVs aWEgd2FzIGZhc3RlciB0aGFuIFB5dGhvbiBmb3IgbW9zdCB0aGluZ3MuIFRoaXMgaXMgcHJvYmFi bHkgYW4gYXJ0aWZhY3Qgb2YgdGhlIHR5cGUgb2YgYWxnb3JpdGhtcyB3ZSB1c2VkLiBPZnRlbiB3 ZSB3b3VsZCBkZWZpbmUgYW4gb3BlcmF0b3IgdGhhdCBsb29wcyBvdmVyIGEgZ3JpZCwgYW5kIHRo ZW4gaXRlcmF0ZSBvbiB0aGF0IG9wZXJhdG9yIHVudGlsIHdlIGZpbmQgYSBmaXhlZCBwb2ludC4g QmVjYXVzZSBvZiB0aGlzIGxvb3BpbmcsIEp1bGlhIGhhcyBhICBwcmVkaWN0YWJsZSBzcGVlZCBh ZHZhbnRhZ2UuPC9wPjxzcGFuPgo8YmxvY2txdW90ZSBzdHlsZT0ibWFyZ2luOjEuMmVtIDBweDti b3JkZXItbGVmdC13aWR0aDo0cHg7Ym9yZGVyLWxlZnQtc3R5bGU6c29saWQ7Ym9yZGVyLWxlZnQt Y29sb3I6cmdiKDIyMSwyMjEsMjIxKTtwYWRkaW5nOjBweCAxZW07Y29sb3I6cmdiKDExOSwxMTks MTE5KTtxdW90ZXM6bm9uZSI+CjxwIHN0eWxlPSJtYXJnaW46MS4yZW0gMHB4IWltcG9ydGFudCI+ V2VyZSB0aGVyZSBtYWpvciBhcmVhcyB3aGVyZSBKdWxpYSBsYWdnZWQgYmVoaW5kIFB5dGhvbj88 L3A+CjwvYmxvY2txdW90ZT4KPC9zcGFuPjxwIHN0eWxlPSJtYXJnaW46MS4yZW0gMHB4IWltcG9y dGFudCI+SSBjYW4gdGhpbmsgb2YgdHdvIHBsYWNlcyB3aGVyZSBwZXJmb3JtYW5jZSBpbiBKdWxp YSB3YXNu4oCZdCBhcyBnb29kIGFzIHBlcmZvcm1hbmNlIGluIHB5dGhvbjo8L3A+CjxvbCBzdHls ZT0ibWFyZ2luOjEuMmVtIDBweDtwYWRkaW5nLWxlZnQ6MmVtIj4KPGxpIHN0eWxlPSJtYXJnaW46 MC41ZW0gMHB4Ij5XZSBvZnRlbiBuZWVkIHRvIGRvIHF1YWRyYXR1cmUgaW4gdGhlIGlubmVybW9z dCBwYXJ0IG9mIG91ciBsb29wcyAodG8gYXBwcm94aW1hdGUgZXhwZWN0ZWQgdmFsdWVzKSBhbmQg d2UgZm91bmQgdGhhdCBKdWxpYeKAmXMgPGNvZGUgc3R5bGU9ImZvbnQtc2l6ZTowLjg1ZW07Zm9u dC1mYW1pbHk6Q29uc29sYXMsSW5jb25zb2xhdGEsQ291cmllcixtb25vc3BhY2U7bWFyZ2luOjBw eCAwLjE1ZW07cGFkZGluZzowcHggMC4zZW07d2hpdGUtc3BhY2U6cHJlLXdyYXA7Ym9yZGVyOjFw eCBzb2xpZCByZ2IoMjM0LDIzNCwyMzQpO2JvcmRlci10b3AtbGVmdC1yYWRpdXM6M3B4O2JvcmRl ci10b3AtcmlnaHQtcmFkaXVzOjNweDtib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czozcHg7Ym9y ZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czozcHg7ZGlzcGxheTppbmxpbmU7YmFja2dyb3VuZC1jb2xv cjpyZ2IoMjQ4LDI0OCwyNDgpIj5xdWFkZ2s8L2NvZGU+IHJvdXRpbmUgd2FzIG11Y2ggc2xvd2Vy IDxjb2RlIHN0eWxlPSJmb250LXNpemU6MC44NWVtO2ZvbnQtZmFtaWx5OkNvbnNvbGFzLEluY29u c29sYXRhLENvdXJpZXIsbW9ub3NwYWNlO21hcmdpbjowcHggMC4xNWVtO3BhZGRpbmc6MHB4IDAu M2VtO3doaXRlLXNwYWNlOnByZS13cmFwO2JvcmRlcjoxcHggc29saWQgcmdiKDIzNCwyMzQsMjM0 KTtib3JkZXItdG9wLWxlZnQtcmFkaXVzOjNweDtib3JkZXItdG9wLXJpZ2h0LXJhZGl1czozcHg7 Ym9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6M3B4O2JvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6 M3B4O2Rpc3BsYXk6aW5saW5lO2JhY2tncm91bmQtY29sb3I6cmdiKDI0OCwyNDgsMjQ4KSI+c2Np cHkuaW50ZWdyYXRlLmZpeGVkX3F1YWQ8L2NvZGU+LiBUaGlzIGlzIDxlbT5ub3Q8L2VtPiBhIGZh aXIgY29tcGFyaXNvbiBiZWNhdXNlIHRoZSBhbGdvcml0aG1zIGVtcGxveWVkIGJ5IHRoZSB0d28g ZnVuY3Rpb25zIGFyZSB2ZXJ5IGRpZmZlcmVudC4gU3BlY2lmaWNhbGx5IDxjb2RlIHN0eWxlPSJm b250LXNpemU6MC44NWVtO2ZvbnQtZmFtaWx5OkNvbnNvbGFzLEluY29uc29sYXRhLENvdXJpZXIs bW9ub3NwYWNlO21hcmdpbjowcHggMC4xNWVtO3BhZGRpbmc6MHB4IDAuM
That’s great!
One more tip. If you know that the integration bounds are going to be constant over certain iterations (which is likely given that you are doing value function iteration), it helps performance significantly if you precompute the nodes and weights before the iterations begin, and then simply call do_quad using these same nodes and weights each iteration.
If you do have to have changing bounds, there is a helper function called quadrect(f::Function, n, a, b, kind="lege") that takes a function, number of nodes, bounds (a, b), and an optional argument for the type of nodes and computes nodes/weights for you then callsdo_quad`.
Right now we don’t have any documentation specific to QuantEcon.jl. We are waiting for this issue to be closed in the main Julia repo so that we can have a more stable backend for generating documentation.
All the functionality from QuantEcon.py is implemented in QuantEcon.jl. The only differences are cases where we write the code in a more pythonic or Julian style. As such, the documentation for the python library should provide a pretty good sense of what QuantEcon.jl offers.
In addition to that I would say that there are three other sources for seeing how the code works:
In the time between now and when we get dedicated Julia documentation up feel free to post any questions/issues you have at the new QuantEcon google group or on the QuantEcon.jl issue list.