The two ChangeLog entries since the last release are below. One new example
was added, and some things were changed in order to make R CMD
check
(and the CRAN gate keepers) happy.
Thanks to CRANberries, you can also look at a diff to the previous release 0.1.2. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page2011-12-28 Dirk Eddelbuettel* DESCRIPTION: Release 0.1.3 * src/newRcppDateExample.cpp: switch from std::cout to the new Rcpp::Rcout device available since Rcpp 0.9.8 * src/classicRcppDateExample.cpp: idem * DESCRIPTION: Depends on Rcpp (>= 0.9.9) for Rcpp::Rcout 2011-04-08 Dirk Eddelbuettel * R/RcppDataFrame.R: Added new example for Rcpp::DataFrame * src/RcppDataFrame.cpp: C++ source for new example * man/RcppDataFrame.Rd: Documentation * man/RcppParams.Rd: Small change to suppres a warning
long
and
unsigned long
which broke some packages using Rcpp, and
expecting those types. Ooops.
The complete NEWS entry for 0.9.9; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, you can also look at a diff to the previous release 0.9.8. As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page0.9.9 2012-12-25 o Reverting the 'int64' changes from release 0.9.8 which adversely affect packages using Rcpp: We will re-apply the 'int64' changes in a way which should cooperate more easily with 'long' and 'unsigned long'. o Unit test output directory fallback changed to use Rcpp.Rcheck o Conditioned two unit tests to not run on Windows where they now break whereas they passed before, and continue to pass on other OSs
This release contains a few incremental changes.
Romain, sponsored by
by the Open Source Programs Office at Google, had released a new
package int64 bringing
larger integers to R, and this is now
supported by Rcpp
as well.
John Chambers contributed some code to have Reference Classes extend existing
C++ classes (typically brought in via Rcpp Modules).
Jelmer Ypma sent us a patch to add a Rcout
device
not unlike cout
, but aligned with R's io buffering.
We added some more unit tests, and made a few small fixes here or there.
The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, you can also look at a diff to the previous release 0.9.7. As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page0.9.8 2011-12-21 o wrap now handles 64 bit integers (int64_t, uint64_t) and containers of them, and Rcpp now depends on the int64 package (also on CRAN). This work has been sponsored by the Google Open Source Programs Office. o Added setRcppClass() function to create extended reference classes with an interface to a C++ class (typically via Rcpp Module) which can have R-based fields and methods in addition to those from the C++. o Applied patch by Jelmer Ypma which adds an output stream class 'Rcout' not unlike std::cout, but implemented via Rprintf to cooperate with R and its output buffering. o New unit tests for pf(), pnf(), pchisq(), pnchisq() and pcauchy() o XPtr constructor now checks for corresponding type in SEXP o Updated vignettes for use with updated highlight package o Update linking command for older fastLm() example using external Armadillo
Call for Papers:
R/Finance 2012: Applied Finance with R
May 11 and 12, 2012
University of Illinois, Chicago, IL, USA
The fourth annual R/Finance conference for applied finance using R will be held on May 11 and 12, 2012 in Chicago, IL, USA on the campus of the University of Illinois at Chicago. The two-day conference will cover topics including portfolio management, time series analysis, advanced risk tools, high-performance computing, market microstructure, and econometrics. All will be discussed within the context of using R as a primary tool for financial risk management, portfolio construction, and trading.
Over the past three years, R/Finance has included attendees from around the world and featured keynote presentations from prominent academics and practitioners. We anticipate another exciting line-up for 2012 --- including keynote presentations from Blair Hull, Paul Gilbert, Rob McCulloch, and Simon Urbanek.
We invite you to submit complete papers or one-page abstracts (in txt or pdf format) for consideration. Academic and practitioner proposals related to R are encouraged. We welcome submissions for full talks, abbreviated "lightning talks", and for a limited number of (longer) pre-conference seminar sessions.
Presenters are strongly encouraged to provide working R code to accompany the presentation/paper. Data sets should also be made public for the purposes of reproducibility (though we realize this may be limited due to contracts with data vendors). Preference may be given to presenters who have released R packages.
Travel and accommodation grants may be available for selected presenters at the discretion of the committee. In addition, the conference will award prizes for best papers. To be eligible for a best paper award, a submission must be a full paper. Extended abstracts, even if a full paper by conference time, are not eligible for a best paper award.
Please send submissions to: committee at RinFinance.com.
The submission deadline is January 31, 2012. Submitters will be notified of acceptance via email by February 28, 2012. Notification of whether a presentation will be a long presentation or a lightning talk will also be made at that time.
Additional details will be announced at this website as they become available. Information on previous year's presenters and their presentations are also at the conference website R/Finance 2009, 2010 and 2011.
For the program committee:
Gib Bassett, Peter Carl, Dirk Eddelbuettel, Brian Peterson,
Dale Rosenthal, Jeffrey Ryan, Joshua Ulrich
So see you in Chicago in May!
Update: Corrected urls to past conference thanks to heads-up by Josh. Thanks!
Courtesy of CRANberries, there is also a diffstat reports for 0.2.34 relative to 0.2.33 As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.34 2011-12-12 o Upgraded to Armadillo release 2.4.2 * clarified documentation for .reshape() * fix for handling of empty matrices by .resize()
The big news for this release is that Windows applications once again run! James
Bates gets full credit for noticing why Windows binaries died on startup,
and provided a short patch which we (after some further simplicifcation)
added. So for the first time since the 0.2.0 release, Windows users can just change
into the examples/standard
directory and issue a simple
make -f Makefile.win
, and the twelve example binaries will
actually work. Yay, and kudos to James.
The other main addition is a new examples directory examples/wt
containing the web-application of the density estimation demo I
had
blogged about
last week. By combining the Wt
toolkit with RInside, we get C++
"web" applications containing R which
is pretty nifty. The example otherwise follows the
earlier
Qt-based example of a standard desktop application with
RInside.
One minor snafu I just noticed is that I was overzealous with the
.Rbuildignore
file. By excluding the wt
and qt
binaries, I also excluded
their source files with the same name (up to the .cpp or .h ending). If you
desire to run the examples, just grab these examples files from the
SVN repo at R-Forge.
All changes since the last release are summarized below:
CRANberries also provides a short report with changes from the previous release. More information is on the RInside page. Questions, comments etc should go to the rcpp-devel mailing list off the Rcpp R-Forge page.0.2.5 2011-12-07 o Applied (somewhat simplified) patch by James Bates which restores RInside to working on Windows -- with a big Thank You! to James for fixing a long-standing bug we inadvertendly introduced right after 0.2.0 almost two years ago o New example embedding R inside a Wt (aka Webtoolkit, pronounced 'witty') application, mirroring the previous Qt application o Qt example qtdensity now uses the new svg() device in base R; removed test for cairoDevice package as well as fallback png code o Very minor fix to qmake.pro file for Qt app correcting link order
The slides are now up at the top of my presentations page.
Courtesy of CRANberries, there is also a diffstat reports for 0.2.33 relative to 0.2.32 As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.33 2011-12-07 o Upgraded to Armadillo release 2.4.1 * added .resize() * fix for vector initialisation
The NEWS entries summarising the changes since the 2.2.* series, we already saw most of this with the two prerelease 0.2.30 and 0.2.31:
Courtesy of CRANberries, there is also a diffstat reports for 0.2.32 relative to 0.2.31 As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.32 2011-12-04 o Upgraded to Armadillo test release 2.4.0 "Loco Lounge Lizard" o Minimal changes relative to 0.2.31 based on 2.3.92, next section is relative to the previous stable release series 2.2.* of Armadillo * added shorter forms of transposes: .t() and .st() * added optional use of 64 bit indices, allowing matrices to have more than 4 billion elements * added experimental support for C++11 initialiser lists * faster pinv() * faster inplace transpose * faster handling of expressions with diagonal views * fixes for handling expressions with aliasing and submatrices * fixes for linking on Ubuntu and Debian systems * fixes for inconsistencies in interactions between matrices and cubes * refactored code to eliminate warnings when using the Clang C++ compiler * .print_trans() and .raw_print_trans() are deprecated
The example was simple yet powerful: a reimplementation of the standard GUI application of a standard density estimate. Here the user can pick a kernel density function from a selection, and also slide a bandwidth parameter. One nice addition was an entry field already populated with a simple expression for a mixture of Normals, allowing for arbitrary random distributions over which to estimate. The example is pretty (thanks to Qt), and was added to RInside with the last CRAN release 0.2.4. The blog post has a nice screenshot.
I had long wondered how to do something similar 'on the web'. Web integration and application frameworks are of course a dime a dozen: Just about any language offers this, with more or less ease. But I wanted something simple yet powerful and fast. And I did not like the idea of a multi-tier app, or of a multi-language mix. I remember having seen something about a web-application framework not unlike Qt, and studying the very useful Wikipedia web application framework comparison I re-discovered Wt (pronounced "Witty"). So there it is, using C++ which brings us ample performance, the ability to connect to a number of libraries and applications (which is important in my quantitatively-minded workd) and avoid the whole multi-tier, multi-language combination. The Wt website has a few more good reason why this may be a suitable idea; the toolkit also offers a very decent amount of features and is amply documented with a fair number of examples.
And after just a little bit poking around during two weekends, I now have the following webapp committed in the SVN repository of RInside, and it is all implemented in in less than two hundred (generously commented) lines of code.
It is currently up and running at the address shown in the screenshot, so give it a go (though I may take it down at another point in time). I quite like it: The application is responsive: changes in the radio buttons (for the density), or the bandwidth, each trigger reestimation of the density, and a new and updated chart is displayed immediately with no noticeable delay---just like the desktop application did.
Best of all, the code logic is essentially unchanged from the Qt-based app. Signals and slots related events to actions, the layout is in terms of standard GUI boxen and containers. And best of all, I did not have to write a line of html, javascript, css or ajax: it is all handled by the Wt toolkit. I was able to drive the app from an Android phone, my tablet, various computers around the house, and had a few friends poke a stick at it from afar.
There is at one open issue. Wt launches new instances of the application object with each connection, which is a very clean model. That doesn't map perfectly with R (which is single-threaded) and RInside (which runs as a singleton for the same reason). So right now, each action sends its state back to the client. In other words, each clients own its parameters and well as vector of random numbers. Each new action sends these back to the app which passes it to R, launches the re-estimation and gets an updated chart back which is then shown by the the client. That is not perfect, and maybe a forking model as used by Simon's RServe would be better, though it would require a rewrite of RInside. Not sure if we get there anytime soon. And for simple applications not facing legions of concurrent users, the singleton should still work. It's a proof of concept at this point. Feedback welcome, and RInside and Rcpp questions should go to the rcpp-devel list as usual.
The NEWS entries summarising the changes for both are below:
Courtesy of CRANberries, there is also a diffstat reports for 0.2.31 relative to 0.2.30 As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.31 2011-11-28 o Upgraded to Armadillo test release 2.3.92 "Loco Lounge Lizard (Beta 2)" * fixes for linking on Ubuntu and Debian systems * fixes for inconsistencies in interactions between matrices and cubes
The success of CRAN is due to a lot of hard work by the CRAN maintainers, lead for many years and still today by Kurt Hornik whose dedication is unparalleled. Even at the current growth rate of several packages a day, all submissions are still rigorously quality-controlled using strong testing features available in the R system.
And for all its successes, and without trying to sound ungrateful, there have always been some things missing at CRAN. It has always been difficult to keep a handle on the rapidly growing archive. Task Views for particular fields, edited by volunteers with specific domain knowledge (including yours truly) help somewhat, but still cannot keep up with the flow. What is missing are regular updates on packages. What is also missing is a better review and voting system (and while Hadley Wickham mentored a Google Summer of Code student to write CRANtastic, it seems fair to say that this subproject didn't exactly take off either).
Following useR! 2007 in Ames, I decided to do something and noodled over a first design on the drive back to Chicago. A weekend of hacking
lead to CRANberries. CRANberries uses existing R functions to learn which packages
are available right now, and compares that to data stored in a local SQLite database. This is enough to learn two things: First, which
new packages were added since the last run. That is very useful information, and it feeds a website with blog
subscriptions (for the technically minded: an RSS feed, at this URL).
Second, it can also compare current versions numbers with the most recent stored
version number, and thereby learns about updated packages. This too is useful, and also feeds a website and RSS
stream (at this URL; there is also a combined one for new and updated packages.) CRANberries
writes out little summaries for both new packages (essentially copying what the DESCRIPTION file contains), and a quick
diffstat
summary for updated packages. A static blog compiler munges this into static html pages which I serve from here, and
creates the RSS feed data at the same time.
All this has been operating since 2007. Google Reader tells me the the RSS feed averages around 137 posts per week, and has about 160 subscribers. It does feed to Planet R which itself redistributes so it is hard to estimate the absolute number of readers. My weblogs also indicate a steady number of visits to the html versions.
The most recent innovation was to add tweeting earlier in 2011 under the @CRANberriesFeed
Twitter handle. After all, the best
way to address information overload and too many posts in our RSS readers surely is to ... just generate more information and add some Twitter
noise. So CRANberries now tweets a message for each new package, and a summary
message for each set of new packages (or several if the total length exceeds the 140 character limit). As of today, we have sent 1723
tweets to what are currently 171 subscribers. Tweets for updated packages were added a few months later.
Which leads us to today's innovation. One feature which has truly been missing from CRAN was updates about withdrawn packages. Packages can be withdrawn for a number of reasons. Back in the day, CRAN carried so-called bundles carrying packages inside. Examples were VR and gregmisc. Both had long been split into their component packages, making VR and gregmisc part of the set of packages no longer on the top page of CRAN, but only its archive section. Other examples are packages such as Design, which its author Frank Harrell renamed to rms to match to title of the book covering its methodology. And then there are of course package for which the maintainer disappeared, or lost interest, or was unable to keep up with quality requirements imposed by CRAN. All these packages are of course still in the Archive section of CRAN.
But how many packages did disappear? Well, compared to the information accumulated by CRANberries over the years, as of today a staggering 282 packages have been withdrawn for various reasons. And at least I would like to know more regularly when this happens, if only so I have a chance to see if the retired package is one the 120+ packages I still look after for Debian (as happened recently with two Rmetrics packages).
So starting with the next scheduled run, CRANberries
will also report removed packages, in its own subtree of the website and its own RSS feed (which should appear at
this URL). I made the required code changes (all of about two
dozen lines), and did some light testing. To not overwhelm us all with line noise while we catch up to the current steady state of packages, I
have (temporarily) lowered the frequency with which CRANberries is called by cron
.
I also put a cap on the number of removed packages that are reported in each run. As always with new code, there may be a bug or two but I
will try to catch up in due course.
I hope this is of interest and use to others. If so, please use the RSS feeds in your RSS readers, and subscribe to the
@CRANberriesFeed
, And keep using CRAN, and let's all say thanks to Kurt, Stefan, Uwe, and
everybody who is working on CRAN (or has been in the past).
Fast-forward a few years. A caretaker group had maintained the package in the meantime, but without really writing any new code. But thanks to the tireless efforts of Tomoaki Nishiyama, who not only wrote a lot of new code addressing some of issues logged at the Google Code project page, but also stepped forward and became the new lead maintainer, things are much, much better now.
The first 0.2-0 release a few weeks ago already addressed a rather large number of issues,
bringing the feature set much closer to what one would expect from a feature-complete
package. But one big thorn remained: builds on Windows still required a
local PostgreSQL library installation as well as local compilation. And as we
can tell from the mailing list(s), this is a little daunting for many
potential users. But what did release 0.2-1 bring: a complete set of libpq
sources so that builds on Windows no longer require presence of local
PostgreSQL sources! We tested this using Uwe Ligges' excellent
win-builder service for R, and
after I reminded Uwe on the weekend to no longer blacklist build attempts of
RPostgreSQL, we
now have Windows binaries for direct installation. Just call
install.packages()
, and you're good to go -- much nicer!
Tomoaki achieved this pretty much single-handedly, and for that reason he greatly deserves some extra praise as an unsung Open Source hero!
Armadillo is a wonderfully expressive (thanks to clever modern template programming), powerful yet simple-to-use C++ library for linear algebra, making expressions in C++ as easy as writing in Matlab or R. By deploying our seamless Rcpp glue between R and C++, RcppArmadillo brings this nice C++ library to R users. The CRAN page for RcppArmadillo now lists ten packages using the RcppArmadillo package.
There was also an earlier bug-fix release 0.2.29 which I had not blogged about separately. The NEWS entries summarising the changes for both are below:
Courtesy of CRANberries, there are also diffstat reports for 0.2.30 relative to 0.2.29 and for 0.2.29 relative to 0.2.28. As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.30 2011-11-19 o Upgraded to Armadillo test release 2.3.91 "Loco Lounge Lizard (Beta 1)" * added shorter forms of transposes: .t() and .st() * added optional use of 64 bit indices, allowing matrices to have more than 4 billion elements * added experimental support for C++11 initialiser lists * faster pinv() * faster inplace transpose * bugfixes for handling expressions with aliasing and submatrices * refactored code to eliminate warnings when using the Clang C++ compiler * .print_trans() and .raw_print_trans() are deprecated 0.2.29 2011-09-01 o Upgraded to Armadillo release 2.2.3 * Release fixes a speed issue in the as_scalar() function.
So if you can make it to the Thomas building of the Fred Hutchinson Cancer Research Center in Seattle, WA, on December 7, I would love to see you there. I have some ideas about freshening up the presentation(s) based on material Romain and I have used in the past. This should make the why as well as how a little clearer; now I just have to find some to put this together. And if there are particular aspects you would like to see covered, please do get in touch with me.
Now this requires some context. Earlier in the year, I had tweeted briefly about a Kurt Elling live concert still streaming on NPR, and truth be told, I have listened to Kurt Elling a whole lot ever since. The most recent album The Gate is fantastic, the Grammy-winner Dedicated to You (which retakes the very famous Coltrane/Hartman album) is beyond words, and The Messenger is worth it just for 'Nature Boy' and the funkiest-ever 'April in Paris'. I also saw him as part of a larger and otherwise rather neat tour. But I needed to see the man himself. So following what one can see from his touring calendar, I jotted down two October dates. Kurt Elling at the Green Mill. Fine. That was earlier in the summer.
Summer has a tendency of evaporating quickly, so here we were in October. And getting going late on Friday, so by the time we got the Green Mill, a long line had formed and we ended up paying tribute to the line for fourty-five minutes with nothing to show. Sad. Home we went, and no live music.
But somehow we mustered the energy to go again last night and thought we were early, arriving about 20 minutes before the show was to start. Ha! Others had appeared at 3pm, by 5pm all seats were gone. We were literally the last ones the get in after a short spell in a shorter line, and standing room-only it was. Oh, but what a treat we got. The set for these two days was Kurt Elling with the fourteen piece Klüvers Big Band from Denmark. They played for three marvellous sets, and well over four hours (with two 25 minute breaks). Pieces often alternated between big band arrangements and smaller pieces by Elling's standard rhythm band, and covered standards as well as Elling's catalogue. As I mentioned earlier on a short post (with pictures) on Google+, it is essentially impossible to not fall for Elling's stage presence when being so close to the stage. The man is just that good.
Elling and the Klüvers Big Band will now play for six nights at Birdland in New York followed by a night each in Washington, DC, and Boston. If you're around, do yourself a favour and go out to see them.
We are happy to report that the number of registrations has met our initial targets. But as a number of open slots remain, we have decided to offer a few places at discounts of 25% for academics (with code acad1) and 50% for students (with code student). Course details are at the Revolution course page, registration is at the Eventbrite page.
And just for completeness, here is what I wrote in the previous announcement:
The format will follow the workshop Romain and I gave during the tutorial day preceding this year's R/Finance conference. The style will once again be hands-on, with copious concrete examples and solid coverage of most aspects of Rcpp and related packages such as RInside, RcppArmadillo and others. The eight-hour schedule contains about six hours of instruction, split into four sessions of around ninety minutes. This leaves ample time for both lunch and coffee breaks, and for informal discussions and Q+A.Feel free to contact me at the usual email address with questions. Or with suggestions for the after-party in San Francisco :)The one-day class will be offered in San Franciso on Saturday, October 8, 2011. Please see the official course page for more details, concrete location info and maps as well as registration details.
This release contains two contributed fixes. The first, suggested by Darren Cook via the rcpp-devel mailing list, corrects how we had set up exceptions specifications, reflecting a bit of Java-think on our part. The idiom is generally discouraged in C++, and we now conform. The second came in two excellent patches by R Core member Martyn Plummer which finally get us compilation on Solaris. This is much appreciated as our hands were tied here for lack of access to such a box.
Otherwise, two new examples and a new unit test were added. The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, you can also look at a diff to the previous release 0.9.6. As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page0.9.7 2011-09-29 o Applied two patches kindly provided by Martyn Plummer which provide support for compilation on Solaris using the SunPro compiler o Minor code reorganisation in which exception specifiers are removed; this effectively only implements a run-time (rather than compile-time) check and is generally seen as a somewhat depreated C++ idiom. Thanks to Darren Cook for alerting us to this issue. o New example 'OpenMPandInline.r' in the OpenMP/ directory, showing how easily use OpenMP by modifying the RcppPlugin output o New example 'ifelseLooped.r' showing Rcpp can accelerate loops that may be difficult to vectorise due to dependencies o New example directory examples/Misc/ regrouping the new example as well as the fibonacci example added in Rcpp 0.9.6 o New Rcpp-FAQ example warning of lossy conversion from 64-bit long integer types into a 53-bit mantissa which has no clear fix yet. o New unit test for accessing a non-exported function from a namespace
Bryan Lewis, who is doing very stuff with websockets and Html5 as he demoed
last week the Chicago R User Group meeting, needed raw
support
and was kind enough to send a patch. After some more testing, this change set
is now in the new version which went onto
CRAN earlier today.
CRANberries provides the usual summary of changes to version 0.5.0.
As usual, our package is available via the R-Forge page leading to svn and tarball access, my digest page and the local directory here.
The race went well enough. I had been racing twice a year at this distance, but took a break after running with some minor injury and generally not too well (see e.g. my writeup from last year's Boston and Chicago marathons). So I wasn't even sure I'd run one this year at all, but the bug got me again when two friends signed up for this, and off we went to train over the summer. So with a few more miles from training, I was pretty antsy and went out too fast as usual, and paid with an as-usual slower half and few short walking breaks past mile 20. But I beat the hope-for target time of 3:25 quite handily with a 3:19:03 -- or a 7:36 min/mile pace. Which (as I noted in a quick post to Google+ started right after the race, and since edited/expanded -- prods to Google+) should hopefully get me back to Boston next spring.
Rf_KillAllDevices()
when you do not have any graphics device. Doh.
So with apologies for the lower quality release, and the two hour malfuntioning window for
CRANberries
that it cause, a repaired version is now out there.
The very brief (upstream) ChangeLog
is as follows:
2011-09-17 Dirk Eddelbuettel* configure.in: Mark as release 0.1.5 * littler.c (littler_CleanUp): Remove call to Rf_KillAllDevices()
littler provides r
(pronounced littler), a shebang / scripting / quick eval / pipelining
front-end to the the R language and data analysis environment.
As usual, our code is available via our svn archive or from tarballs off my littler page and the local directory here. A fresh package is in Debian's incoming queue and will hit mirrors shortly.
ld
linker uses the --as-needed
option (as
Ubuntu builds now do): all it took was a little reordering of arguments.
With that, I did a little cleanup as it has been a while since
version 0.1.3.
The brief (upstream) ChangeLog
is as follows:
2011-09-15 Dirk Eddelbuettel* configure.in: Mark as release 0.1.4 * Makefile.am: Applied patch by Mathias Klose to prevent FTBFS with 'ld --as-needed', cf LP bug 770980. * littler.c: A few small tweaks suggested by 'gcc -Wall' * examples/install2.r: Added a second R package installer example * examples/update.r: Switch to '/usr/bin/r -t' as shebang line * examples/fsizes.r: Dito * littler.c: Update copyrights to 2011 * README: Idem
littler provides r
(pronounced littler), a shebang / scripting / quick eval / pipelining
front-end to the the R language and data analysis environment.
As usual, our code is available via our svn archive or from tarballs off my littler page and the local directory here. A fresh package is in Debian's incoming queue and will hit mirrors shortly.
Thanks to Helmut Heiming who noticed a side-effec t from the
DiscountCurve
functions: the Quantlib-global variable
determining the evaluation date was overriden; this could affect subsequent
curve-related pricers. This is now fixed, and we added a new function
setEvaluationDate
to set this date from R too. We added this
call in some of the examples in the manual pages. Otherwise two very minor
build system tweaks were added, but no other changes were made
Thanks to CRANberries, there is also a diff to the previous release 0.3.7. Full changelog details, examples and more details about this package are at my RQuantLib page.
This leads to very straightforward implementations using recursion:
## R implementation of recursive Fibonacci sequence fibR <- function(n) { if (n == 0) return(0) if (n == 1) return(1) return (fibR(n - 1) + fibR(n - 2)) }
Unfortunately, this elegant implementation which remain close to the abtract formulation of the recurrence algorithm performs very poorly in R as there is noticeable overhead in function calls which becomes dominant in a recursion. This lead to the original question on StackOverflow, and the accepted answer uses a trick presented by Pat Burns in his lovely R Inferno: rewrite the solution using a computer science trick called memoization:
fibonacci <- local({ memo <- c(1, 1, rep(NA, 100)) f <- function(x) { if(x == 0) return(0) if(x < 0) return(NA) if(x > length(memo)) stop("'x' too big for implementation") if(!is.na(memo[x])) return(memo[x]) ans <- f(x-2) + f(x-1) memo[x] <<- ans ans } })
That is a fair answer, and even more was suggested with a link to a terrific analysis calling the Fibonacci recurrence the worst algorithm in the world. That is also fair, but all the basic research into better algorithms exploiting some structure of the problem to advance performance (and of course understanding) is overlooking one crucial part: algorithm analysis is essentially independent of the language. So whatever improvements we obtain by thinking really hard about a problem are then available for other implementations too.
So with a tip of the hat to the old Larry Wall quote about Lazyness, Impatience and Hubris, I would like to suggest what I consider a much simpler route to much better performance: recode it in C++ using both Rcpp (for the R/C++ integration) and inline for the on-the-fly compilation, linking and loading of C++ code into R.
## inline to compile, load and link the C++ code require(inline) ## we need a pure C/C++ function as the generated function ## will have a random identifier at the C++ level preventing ## us from direct recursive calls incltxt <- ' int fibonacci(const int x) { if (x == 0) return(0); if (x == 1) return(1); return (fibonacci(x - 1)) + fibonacci(x - 2); }' ## now use the snippet above as well as one argument conversion ## in as well as out to provide Fibonacci numbers via C++ fibRcpp <- cxxfunction(signature(xs="int"), plugin="Rcpp", incl=incltxt, body =' int x = Rcpp::as<int>(xs); return Rcpp::wrap( fibonacci(x) ); ')
This single R function call cxxfunction()
takes the code
embedded in the arguments to the body
variable (for the core
function) and the incltxt
variable for the helper function we
need to call. This helper function is needed for the recursion as
cxxfunction()
will use an randomized internal identifier for the
function called from R preventing us from calling this (unknown) indentifier.
But the rest of the algorithm is simple, and as beautiful as the initial
recurrence. Three lines, three statements, and three cases for F(0), F(1) and
the general case F(n) solved by recursive calls. This also illustrates how
easy it is to get an integer
from R to C++ and back: the
as
and wrap
simply do the right thing
converting to and from the SEXP
types used internally by the C
API of R.
A performance comparison of the basic R version fibR
, its
byte-compiled variant fibRC
and
and the C++ version fibRcpp
shown above is very compelling.
We have added a file fibonacci.r
to the large and still growing
set of examples included with Rcpp, and we can just
execute that script with Rscript
or (as here) r
from the littler package:
So the recursion for the original argument of N=35 takes just over a minute at about 61.5 and 61.9 seconds, respectively, for the R version and its byte-compiled variant (as per the column titled elapsed). So byte-compilation essentially offers no help for the bottleneck of slow function calls.edd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/Misc$ r fibonacci.r Loading required package: inline Loading required package: methods Loading required package: compiler test replications elapsed relative user.self sys.self 3 fibRcpp(N) 1 0.092 1.0000 0.09 0.00 2 fibRC(N) 1 61.480 668.2609 61.47 0.00 1 fibR(N) 1 61.877 672.5761 61.83 0.02 edd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/Misc$
The C++ versions relying on Rcpp which created in a few lines of code and a
single call to cxxfunction
however takes just 92
milliseconds---or a relative gain of well over six-hundred times.
That provides another nice demonstration of what Rcpp can do. Improved algorithms for well-understood problems are surely one way to accelerate solutions. But there are (many ?) times when we do not have the luxury of being able to think through to a new and improved approach. Or worse, such an approach may even introduce new errors or inaccurracies if we get it wrong on a first try. With Rcpp, we are able to the express the problem as written in its original statement: a simple recursion. The gain relative to a slow R implementation is noteworthy---and could of course be improved further if we really needed to by relying on better algorithms like memoization. But for day to day tasks, I gladly take speedups of (up to) a few hundred times thanks to Rcpp without having to do hard algorithmic work.
Before closing, a quick reminder that I will be giving two classes on Rcpp in a few weeks. These will be in New York on September 24, and San Franciso on October 8, see this blog post as well as this page at Revolution Analytics (who are a co-organiser of the classes) for details and registration information.
By the time I saw that question yesterday evening, Josh Ulrich had already posted a nice answer suggesting
to switch from ifelse
to if
to escape the overhead of a vectorised expression on simple scalars. I meekly added a comment
suggesting that Rcpp would likely do well on this and that someone should volunteer
such an answer. Well, it is still August and Mr. Someone is on holiday, so this morning I followed up with such an answer. And as it turns out to
work quite well indeed, we will repost it here.
Let's start with the general setup, and the two functions supplied by Josh. We also byte-compile these using the compiler
package which
is the culmination of several years of work by R core member Luke Tierney. This package was added to R
during the last major release, and we assessed it
in this earlier blog post as well as several Rcpp-related
follow-ups. We also load the packages for on-the-fly 'inline' compilation and easy benchmarking:
library(inline) library(rbenchmark) library(compiler) fun1 <- function(z) { for(i in 2:NROW(z)) { z[i] <- ifelse(z[i-1]==1, 1, 0) } z } fun1c <- cmpfun(fun1) fun2 <- function(z) { for(i in 2:NROW(z)) { z[i] <- if(z[i-1]==1) 1 else 0 } z } fun2c <- cmpfun(fun2)
We see that basic worker just assign to the i-th element based on the preceding element. Function two uses the aforementioned
if
statement, and both are also byte-compiled.
Writing the same code in C++ using both Rcpp (for the R/C++ integration) and inline for the on-the-fly compilation, linking and loading of C++ code into R is pretty straightforward too:
funRcpp <- cxxfunction(signature(zs="numeric"), plugin="Rcpp", body=" Rcpp::NumericVector z = Rcpp::NumericVector(zs); int n = z.size(); for (int i=1; i<n; i++) { z[i] = (z[i-1]==1.0 ? 1.0 : 0.0); } return(z); ")
This single R function call takes the code embedded in the argument to the body
variable, builds a complete function in temporary file,
and then compiles, links and loads it. We can now call funRcpp()
just like the other four functions and do so via the
benchmark()
function of the rbenchmark package.
R> z <- rep(c(1,1,0,0,0,0), 100) R> identical(fun1(z),fun2(z),fun1c(z),fun2c(z),funRcpp(z)) [1] TRUE R> R> res <- benchmark(fun1(z), fun2(z), + fun1c(z), fun2c(z), + funRcpp(z), + columns=c("test", "replications", "elapsed", "relative", "user.self", "sys.self"), + order="relative", + replications=1000) R> print(res) test replications elapsed relative user.self sys.self 5 funRcpp(z) 1000 0.005 1.0 0.01 0 4 fun2c(z) 1000 0.482 96.4 0.48 0 2 fun2(z) 1000 1.989 397.8 1.98 0 3 fun1c(z) 1000 11.365 2273.0 11.37 0 1 fun1(z) 1000 13.210 2642.0 13.21 0
We can focus on the columns labelled elapsed and relative. The C++ version is faster by a factor of almost one-hundred compared to the byte-compiled version of funtion2, and almost four-hundred times faster than the plain-R variant of function2. And function1 is even worse, coming at well over twenty-two-hundred times the run-time of the C++ version. Byte-compilation also helps little here.
For comparison, we also ran the original example of a very short vector, called more frequently:
The qualitative ranking is unchanged: the Rcpp version dominates. Function2 usingR> z <- c(1,1,0,0,0,0) R> res2 <- benchmark(fun1(z), fun2(z), + fun1c(z), fun2c(z), + funRcpp(z), + columns=c("test", "replications", "elapsed", "relative", "user.self", "sys.self"), + order="relative", + replications=10000) R> print(res2) test replications elapsed relative user.self sys.self 5 funRcpp(z) 10000 0.047 1.00000 0.04 0 4 fun2c(z) 10000 0.134 2.85106 0.13 0 2 fun2(z) 10000 0.328 6.97872 0.32 0 3 fun1c(z) 10000 1.080 22.97872 1.08 0 1 fun1(z) 10000 1.243 26.44681 1.24 0
if
instead of the vectorised ifelse
is second-best with the byte-compiled version being about twice as fast that the plain R
variant, but still almost three times slower than the C++ version. And the relative differences are less pronounced: relatively speaking, the
function call overhead matters less here and the actual looping matters more: C++ gets a bigger advantage on the actual loop operations in the longer
vectors. That it is an important result as it suggests that on more real-life sized data, the compiled version may reap a larger benefit.
All in all a nice demonstration of Rcpp, and a gain of almost one-hundred to the best byte-compiled version is nothing to sneeze at---especially when it is so easy to write and load a five-line C++ function thanks to Rcpp.
Before closing, a quick reminder that I will giving two classes on Rcpp in a few weeks. These will be in New York on September 24, and San Franciso on October 8, see this blog post as well as this page at Revolution Analytics (who are a co-organiser of the classes) for details and registration information.
The format will follow the workshop Romain and I gave during the tutorial day preceding this year's R/Finance conference. The style will once again be hands-on, with copious concrete examples and solid coverage of most aspects of Rcpp and related packages such as RInside, RcppArmadillo and others. The eight-hour schedule contains about six hours of instruction, split into four sessions of around ninety minutes. This leaves ample time for both lunch and coffee breaks, and for informal discussions and Q+A.
Two one-day classes will be offered: The first in New York on Saturday, September 28, 2011 and the second one two weeks later in San Franciso on Saturday, October 8, 2011. Please see the official course page for more details, concrete location info and maps as well as registration details.
Feel free to contact me at the usual email address with questions.
The NEWS entry is below; a number of these changes were already in the preceding 0.2.27 release of RcppArmadillo which was base on the beta for Armadillo 2.2.0.
CRANberries provides a diffstat report for 0.2.28 relative to 0.2.27. As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.28 2011-08-02 o Upgraded to Armadillo release 2.2.1 "Blue Skies Debauchery" * faster multiplication of small matrices * faster trans() * faster handling of submatrices by norm() * added economical singular value decomposition: svd_thin() * added circ_toeplitz() * added .is_colvec() & .is_rowvec() * fixes for handling of complex numbers by cov(), cor(), running_stat_vec
This release contains a fix which helps the RppEigen package (mentioned previously on this blog), as well as an addition which permits user-defined finalizers for external pointer objects (following a suggestion on the mailing list). Two new examples where added: a Gibbs sampler illustration (blogged about as well) and a Rcpp-based Fibonacci implementation following a question on StackOverflow. And while that last example is clearly degenerate, the 700+ fold net speedup (as shown in my answer) is still pretty neat.
The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, you can also look at a diff to the previous release 0.9.5. As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page0.9.6 2011-07-26 o Added helper traits to facilitate implementation of the RcppEigen package: The is_eigen_base traits identifies if a class derives from EigenBase using SFINAE; and new dispatch layer was added to wrap() to help RcppEigen o XPtr now accepts a second template parameter, which is a function taking a pointer to the target class. This allows the developper to supply his/her own finalizer. The template parameter has a default value which retains the original behaviour (calling delete on the pointer) o New example RcppGibbs, extending Sanjog Misra's Rcpp illustration of Darren Wilkinson's comparison of MCMC Gibbs Sampler implementations; also added short timing on Normal and Gaussian RNG draws between Rcpp and GSL as R's rgamma() is seen to significantly slower o New example on recursively computing a Fibonacci number using Rcpp and comparing this to R and byte-compiled R for a significant speed gain
Conrad did not rest either and just yesterday released version 2.1.91 as a first step towards a new 2.2.0 release sometime soon. And also yesterday, we wrapped that new version into RcppArmadillo release 0.2.27. With CRAN being back in full swing, we pushed it over there this morning and it already made its way into the repository.
The NEWS entries summarising the changes---which are exclusively upstream---are below:
Courtesy of CRANberries, there are also diffstat reports for 0.2.27 relative to 0.2.26 and for 0.2.26 relative to 0.2.25. As always, more detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.0.2.27 2011-07-22 o Upgraded to Armadillo release 2.1.91 "v2.2 beta 1" * faster multiplication of small matrices * faster trans() * faster handling of submatrices by norm() * added economical singular value decomposition: svd_thin() * added circ_toeplitz() * added .is_colvec() & .is_rowvec() 0.2.26 2011-07-17 o Upgraded to Armadillo release 2.0.2 * fix for handling of conjugate transpose by as_scalar() * fix for handling of aliasing by diagmat() * fix for handling of empty matrices by symmatu()/symmatl()
The example is based on a blog post by Darren Wilkinson which itself discusses and compares the suitability of R, Python, Java or C for MCMC analysis, using the Gibbs sampler as a concrete example. Darren's post is worth checking out: he stresses the rather pragmatic aspects of how fast and/or easy it is to write the code, rather than just the mere runtime. As such, he is not too concerned with a speed advantage of Python over R which he sees at a factor of around 2.4, leaving him to continue to prototype in R. Similarly, with C 'only' being faster than Java by a factor of two, he prefers Java for the numerically more demanding parts.
We do of course advocate the use of Rcpp to combine the best aspects of R and C++, respectively. This Gibbs sampler example provides a nice backdrop. So working with Darren's example, consider the same Gibbs sampler for a bivariate distribution (and apologies for the lack of latex typesetting on my blog)
where the conditional distributions aref(x,y) = k x^2 exp( -x y^2 - y^2 + 2y - 4x)
Sanjog then spotted and corrected a small error in the variance expression in Darren's derivation; this is now acknowledged on Darren's website. Full details are in the R script now committed in SVN. The R code for the Gibbs sample can therefore be written as follows below. Note that this uses thinning to minimize serial correlation in the conditional densities--which renders the computation more demanding as 'N times thin' draws have to be generated:f(x|y) = (x^2)*exp(-x*(4+y*y)) ## a Gamma density kernel f(y|x) = exp(-0.5*2*(x+1)*(y^2 - 2*y/(x+1)) ## a Gaussian kernel
A second variant can be computed using the R bytecode compiler which appeared with the recent release of R 2.13.0 (and which we analysed in this blog post from April). This is as easy as## Here is the actual Gibbs Sampler ## This is Darren Wilkinsons R code (with the corrected variance) ## But we are returning only his columns 2 and 3 as the 1:N sequence ## is never used below Rgibbs <- function(N,thin) { mat <- matrix(0,ncol=2,nrow=N) x <- 0 y <- 0 for (i in 1:N) { for (j in 1:thin) { x <- rgamma(1,3,y*y+4) y <- rnorm(1,1/(x+1),1/sqrt(2*(x+1))) } mat[i,] <- c(x,y) } mat }
Thanks to Rcpp and the inline package, we can also write a C++ variant that can be built and launched from R with ease. The C++ code is assigned to an R text variable## We can also try the R compiler on this R function RCgibbs <- cmpfun(Rgibbs)
gibbscode
. (And we used to typeset such
code on the blog as a character string, ie in a faint red color---but have now switched to highlight it as if it were freestanding C++
code. It really is passed as a single string to R which then uses the cxxfunction()
to compile, link and load a C++ function
built around the code. See previous posts on the inline package for more.)
It is noteworthy how the code logic is essentially identical between the basic R version, and the C++ version. Two nested loops control draws of x from a Gamma distribution, conditional on y, as well as draws of y from a Normal, conditional on x. Add a small amount of parameter passing to obtain the parameters## Now for the Rcpp version -- Notice how easy it is to code up! gibbscode <- ' using namespace Rcpp; // inline does that for us already // n and thin are SEXPs which the Rcpp::as function maps to C++ vars int N = as<int>(n); int thn = as<int>(thin); int i,j; NumericMatrix mat(N, 2); RNGScope scope; // Initialize Random number generator // The rest of the code follows the R version double x=0, y=0; for (i=0; i<N; i++) { for (j=0; j<thn; j++) { x = ::Rf_rgamma(3.0,1.0/(y*y+4)); y = ::Rf_rnorm(1.0/(x+1),1.0/sqrt(2*x+2)); } mat(i,0) = x; mat(i,1) = y; } return mat; // Return to R ' # Compile and Load RcppGibbs <- cxxfunction(signature(n="int", thin = "int"), gibbscode, plugin="Rcpp")
N
and thin
, allocation of a results matrix and setup of the random number generator state
to remain consistent with R, as well as a return of the matrix---and that is all.
As Darren's code uses the GNU GSL in its C variant, I also became interested in seeing how a C/C++ hybrid variant using our RcppGSL package would fare. The code is below.
This code is similar to the version using just Rcpp, but we need to allocate space for the GSL random generator object (and later release that memory allocation), and we do of course call the GSL functions. This also necessitates declaring the function using the two header files listed as arguments for thegslgibbsincl <- ' #include <gsl/gsl_rng.h> #include <gsl/gsl_randist.h> using namespace Rcpp; // just to be explicit ' gslgibbscode <- ' int N = as<int>(ns); int thin = as<int>(thns); int i, j; gsl_rng *r = gsl_rng_alloc(gsl_rng_mt19937); double x=0, y=0; NumericMatrix mat(N, 2); for (i=0; i<N; i++) { for (j=0; j<thin; j++) { x = gsl_ran_gamma(r,3.0,1.0/(y*y+4)); y = 1.0/(x+1)+gsl_ran_gaussian(r,1.0/sqrt(2*x+2)); } mat(i,0) = x; mat(i,1) = y; } gsl_rng_free(r); return mat; // Return to R ' ## Compile and Load GSLGibbs <- cxxfunction(signature(ns="int", thns = "int"), body=gslgibbscode, includes=gslgibbsincl, plugin="RcppGSL")
include
argument of
cxxfunction()
.
So how is the performance?
The script (now committed in Rcpp's SVN repo as
examples/RcppGibbs/RcppGibbs.R
, and also part of the next release) creates the output below when running in non-interactive
mode (whereas interactive mode creates a few charts too):
The first block is a hand-computed comparison using four sets of parameters; the second block uses the excellent rbenchmark package to compare ten runs at twenty-thousand draws.edd@max:~/svn/rcpp/pkg/Rcpp/inst/examples/RcppGibbs$ r RcppGibbs.R Replication # 1 complete Replication # 2 complete Replication # 3 complete Replication # 4 complete N=1000 N=5000 N=10000 N=20000 Elasped Time (R) 0.124 2.650 10.511 41.773 Elasped Time (RC) 0.081 1.916 7.594 30.280 Elapsed Time (Rcpp) 0.003 0.076 0.306 1.221 Elapsed Time (Rgsl) 0.002 0.049 0.196 0.784 SpeedUp Rcomp. 1.530 1.380 1.380 1.380 SpeedUp Rcpp 41.330 34.870 34.350 34.210 SpeedUp GSL 62.000 54.080 53.630 53.280 test replications elapsed relative user.self sys.self 4 GSLGibbs(N, thn) 10 7.845 1.000000 7.84 0 3 RcppGibbs(N, thn) 10 12.218 1.557425 12.22 0 2 RCgibbs(N, thn) 10 312.296 39.808286 311.98 0 1 Rgibbs(N, thn) 10 420.953 53.658764 420.59 0
We see a nominal increase in performance due to the bytecode compiler, saving roughly 38 percent which seems appropriate given that the R code mostly controls the loops; actual work in undertaken in the already compiled RNG functions. The Rcpp variant is about 34 times faster than the pure R code. Sanjog reported higher increases on his OS X machines (and Darren's post echos a similar order of magnitude). However, on my i7 running Linux I always obtained an improvement in the mid- to high thirties. That is certainly already a rather pleasant result.
What surprised and stunned me at first was that the GSL solution scores an improvement of around 53 times (close to the factor of 60
reported by Darren). A closer look at the code (shown above) makes it clear that there are very few compute-intensive operations outside of
the RNG draws. I validated this further with a second study timing just one million draws each from a Gaussian and Gamma using R via Rcpp,
and using the GSL. It turns out that the R code is about 2.5 times slower for random draws from the Gamma distribution than the GSL. Inspection of the
source code---in files src/nmath/rgamma.c
for R and randist/gamma.c
for the GSL shows why. R uses a much more complex
(and presumably more precise) algorithm. I may follow up with Martin Maechler to see if we can illustrative the numerical benefits of this
more expensive approach---this blog entry is getting long enough already.
So to sum up: Gibbs sampling is a somewhat resource-heavy Monte Carlo Markov Chain method for investigating multivariate distributions. R excels at quick and simple explorations, albeit at somewhat slower execution speed. The Rcpp package can help by providing easy means to accelerate simulations by a significant factor. The example discussed here is now in SVN repository for Rcpp and will be part of the next release.
Updated 2011-07-16: Darren has just updated his comparison; fixed two typos here too.
This release comprises a number of minor fixes, extensions as well as small additions to the documentation and examples which have accumulated since the last release in April. The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, there is also a diff to the previous release 0.9.4:0.9.5 2011-07-05 o New Rcpp-FAQ examples on using the plugin maker for inline's cxxfunction(), and on setting row and column names for matrices o New sugar functions: mean, var, sd o Minor correction and extension to STL documentation in Rcpp-quickref o wrap() is now resilient to NULL pointers passed as in const char * o loadRcppModules() gains a "direct" argument to expose the module instead of exposing what is inside it o Suppress a spurious warning from R CMD check on packages created with Rcpp.package.skeleton(..., module=TRUE) o Some fixes and improvements for Rcpp sugar function 'rlnorm()' o Beginnings of new example using OpenMP and recognising user interrupts
ChangeLog | 74 DESCRIPTION | 10 R/00_classes.R | 3 R/Module.R | 16 R/loadRcppModules.R | 10 R/populate.R | 10 R/tools.R | 13 R/zzz.R | 3 cleanup | 2 inst/NEWS | 21 inst/doc/Rcpp-FAQ.pdf |binary inst/doc/Rcpp-FAQ/Rcpp-FAQ.Rnw | 62 inst/doc/Rcpp-extending.pdf |binary inst/doc/Rcpp-introduction.pdf |binary inst/doc/Rcpp-modules.pdf |binary inst/doc/Rcpp-modules/Rcpp-modules.Rnw | 7 inst/doc/Rcpp-package.pdf |binary inst/doc/Rcpp-quickref.pdf |binary inst/doc/Rcpp-quickref/Rcpp-quickref.Rnw | 59 inst/doc/Rcpp-sugar.pdf |binary inst/doc/Rcpp-unitTests.pdf |binary inst/doc/Rcpp.bib | 4 inst/doc/unitTests-results/Rcpp-unitTests.html | 18 inst/doc/unitTests-results/Rcpp-unitTests.txt | 49 inst/examples/OpenMP |only inst/include/Rcpp/Module.h | 33 inst/include/Rcpp/config.h | 2 inst/include/Rcpp/internal/wrap.h | 5 inst/include/Rcpp/module/Module_generated_CppMethod.h | 2902 +++++++++++++++++- inst/include/Rcpp/stats/random/rlnorm.h | 14 inst/include/Rcpp/stats/random/rnorm.h | 4 inst/include/Rcpp/sugar/functions/functions.h | 3 inst/include/Rcpp/sugar/functions/mean.h |only inst/include/Rcpp/sugar/functions/sd.h |only inst/include/Rcpp/sugar/functions/sum.h | 4 inst/include/Rcpp/sugar/functions/var.h |only inst/include/Rcpp/vector/Vector.h | 4 inst/skeleton/zzz.R | 1 inst/unitTests/runit.wrap.R | 25 man/CppClass-class.Rd | 2 man/loadRcppModules.Rd | 6 src/Module.cpp | 1 42 files changed, 3252 insertions(+), 115 deletions(-)
As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page
My talks introducing High Performance Computing with R (see e.g. these slides from a five-hour workshop at the ISM in Tokyo) frequently feature an example of how to extend R with dedicated compiled code for linear regressions. Romain and I also frequently use this a motivating examples with our Rcpp package for seamless R and C++ integration. In fact, the examples directory for Rcpp still contains an earlier version of a benchmark for fastLm(), a faster alternative for R's lm() and lm.fit() functions. We have also extended this with the RcppArmadillo package which brings Conrad Sanderson's excellent Armadillo library with templated C++ code for linear algebra to R, as well as a simple integration to the GNU GSL via our RcppGSL package. The Rcpp section on my blog contains several posts about fastLm benchmarks.
Doug Bates has been a key Rcpp contributor, helping particularly with the initial Armadillo integration. His research, however, also requires highly performing sparse matrix operations which Armadillo does not yet offer. So Doug has started to explore the Eigen project---a free C++ template math library mainly focused on vectors, matrices, and linear algebra (note that we will refer to the Eigen, Eigen2 and Eigen3 APIs as just 'Eigen' here, focusing on the latest version, Eigen3). Better still, Doug went to work and pretty much single-handedly wrote a new package RcppEigen which integrates the templated C++ library Eigen with R using Rcpp.
RcppEigen also provides a fastLm implementation and benchmark script. In fact, it contains a full six different implementations as Doug is keenly interested in rank-revealing decompositions which can guard against ill-conditioned model matrices. Some more background information on this is also available in Doug's article on Least Squares Calculations in R in R News 4(1).
Doug's implementation also uses an elegant design. It comprises a base class with common functionality, and six subclasses which specialize accordingly for these six different decompositions approaches:
On my server, the result of running the included benchmark script lmBenchmark is as follows:
From this first set of results, the preferred method may be 'PivQR', the pivoted QR. Strictly-speaking, it is the only one we can compare to lm.fit() which also uses a pivoting scheme. In the case of a degenerated model matrix, all the other methods, including the four fastest approaches, are susceptible to producing incorrect estimates. Doug plans to make SVD and SymmEig rank-revealing too.lm benchmark for n = 100000 and p = 40: nrep = 20 test relative elapsed user.self sys.self 7 LLt 1.000000 0.918 0.91 0.00 3 LDLt 1.002179 0.920 0.92 0.00 5 SymmEig 3.021786 2.774 2.19 0.57 6 QR 5.136166 4.715 4.24 0.48 2 PivQR 5.303922 4.869 4.27 0.58 8 arma 6.592593 6.052 6.03 0.02 1 lm.fit 9.386710 8.617 7.14 1.45 4 SVD 33.858388 31.082 30.19 0.84 9 GSL 114.972767 105.545 104.79 0.63
As for pure speed, the LL and LDL decomposition have almost identical performance, and are clearly faster than the other approaches. Compared to lm.fit(), which is the best one could do with just R, we see an improvement by a factor of eight which is quite impressive (albeit not robust to rank-deficient model matrices). Apart from the SVD, all approaches using Eigen are faster than the one using Armadillo, which itself is still faster than R's lm.fit(). Doug and I were very surprised by the poor performance of the GNU GSL (which also uses SVD) via RcppGSL.
Now, Eigen uses its own code for all linear algebra operations, bypassing BLAS and LAPACK libraries. The results above were achieved with the current Atlas package in Ubuntu. If we take advantage of the BLAS / LAPACK plug-in architecture offered on Debian / Ubuntu systems (see the vignette in my gcbd package for more) and use Goto BLAS which provide tuning as well as parallelism on multi-core machines, the results are as follow:
We see that the BLAS-using Armadillo approach improves a little and moves just slightly ahead of the pivoted QR. On the other hand, lm.fit(), which also uses a pivoting scheme and hence only level 1 BLAS operations, changes less. GSL performs even worse (and it is unclear why). Doug's post announcing RcppEigen on the Eigen list has a few more sets of results.lm benchmark for n = 100000 and p = 40: nrep = 20 test relative elapsed user.self sys.self 3 LDLt 1.000000 0.907 0.90 0.00 7 LLt 1.000000 0.907 0.91 0.00 5 SymmEig 2.981257 2.704 2.14 0.56 6 QR 5.004410 4.539 4.03 0.50 8 arma 5.072767 4.601 15.30 3.05 2 PivQR 5.307607 4.814 4.27 0.55 1 lm.fit 8.302095 7.530 9.55 12.25 4 SVD 33.015436 29.945 29.06 0.85 9 GSL 195.413451 177.240 244.64 319.89
This post has illustrated some of the performance gains that can be obtained from using Eigen via RcppEigen. When not using rank-revealing methods, computing time can be reduced by up to eight times relative to lm.fit(). Rank-revealing method can still improve by almost a factor of two. The main disadvantage of Eigen may be one of the reasons behind its impressive performance: its heavily templated code does not use BLAS, and the resulting object code (as e.g. in RcppEigen) becomes enormous (when compiling with debugging symbols). As one illustration, the shared library for RcppEigen on my Ubuntu 64-bit system has a size of 24.6 mb whereas RcppArmadillo comes in at a mere 0.78 mb; without debugging symbols it is a more reasonable 0.52 mb.
The performance of Eigen is certainly intriguiging, and its API is rather complete. It seems safe to say that we may see more R projects going to make use of Eigen thanks to the RcppEigen wrapper.
Update: Clarified statement about large object size which was entirely due to building with debugging support.
The NEWS file entries for both releases follow below; they include the aggregate changes some of which were already provided by the pre-releases leading up to Armadillo 2.0.0.
Courtesy of CRANberries, here is the diff to the previous release.0.2.25 2011-06-30 o Upgraded to Armadillo 2.0.1 which fixes two minor compilation issues 0.2.24 2011-06-29 o Upgraded to Armadillo release 2.0.0 "Carnivorous Sugar Glider" * faster multiplication of tiny matrices (≤ 4x4) * faster compound expressions containing submatrices * faster inverse of symmetric positive definite matrices * faster element access for fixed size matrices * added handling of arbitrarily sized empty matrices (eg. 5x0) * added loading & saving of matrices as CSV text files * added .count() member function to running_stat and running_stat_vec * added syl(), strans(), symmatu()/symmatl() * added submatrices of submatrices * det(), inv() and solve() can be forced to use more precise * algorithms for tiny matrices (≤ 4x4) * htrans() has been deprecated; use trans() instead * API change: trans() now takes the complex conjugate when transposing a complex matrix * API change: .is_vec() now outputs true for empty vectors (eg. 0x1) * API change: forms of chol(), eig_sym(), eig_gen(), inv(), lu(), pinv(), princomp(), qr(), solve(), svd(), syl() that do not return a bool indicating success now throw std::runtime_error exceptions when failures are detected * API change: princomp_cov() has been removed; princomp() in conjunction with cov() can be used instead * API change: set_log_stream() & get_log_stream() have been replaced by set_stream_err1() & get_stream_err1()
ChangeLog | 12 +++++ DESCRIPTION | 10 ++-- inst/NEWS | 36 +++++++++++++++- inst/include/armadillo_bits/arma_version.hpp | 10 ++-- inst/include/armadillo_bits/auxlib_meat.hpp | 4 - inst/include/armadillo_bits/diagmat_proxy.hpp | 4 - inst/include/armadillo_bits/fn_misc.hpp | 58 ++++++++++++++------------ inst/include/armadillo_bits/fn_princomp.hpp | 31 +++++++++++++ inst/include/armadillo_bits/subview_meat.hpp | 2 9 files changed, 126 insertions(+), 41 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
A minor internal change was the rearrangement of arguments for the (mostly internal) function fastLmPure
so that it is closer to the R
function lm.fit
which it mimics. The user-facing function for fastLm
, using either the formula method or the default method,
have not changed.
The short NEWS file extract follows below. I also include the entry for the bugfix release 0.2.22 (based on Armadillo 1.99.4) which preceded it, and which does not seem to have gotten its own blog post.
Courtesy of CRANberries, here is the diff to the previous release.0.2.23 2011-05-23 o Upgraded to Armadillo release 1.99.5 "v2.0 beta 5" * Forms of chol(), eig_sym(), eig_gen(), inv(), lu(), pinv(), princomp(), qr(), solve(), svd(), syl() that do not return a bool indicating success now throw std::runtime_error exceptions when failures are detected * princomp_cov() has been removed; princomp() in conjunction with cov() can be used instead * set_log_stream() & get_log_stream() have been replaced by set_stream_err1() & get_stream_err1() * det(), inv() and solve() can be forced to use more precise algorithms for tiny matrices (≤ 4x4) * Added loading & saving of matrices as CSV text files o fastLmPure() now uses same argument order as R's lm.fit() o Export and document S3 methods in NAMESPACE and manual page as such 0.2.22 2011-06-06 o Upgraded to Armadillo release 1.99.4 "v2.0 beta 4" * fixes for handling of tiny matrices
RcppArmadillo-0.2.22/RcppArmadillo/inst/include/armadillo_bits/fn_princomp_cov.hpp |only RcppArmadillo-0.2.22/RcppArmadillo/inst/include/armadillo_bits/op_princomp_cov_bones.hpp |only RcppArmadillo-0.2.22/RcppArmadillo/inst/include/armadillo_bits/op_princomp_cov_meat.hpp |only RcppArmadillo-0.2.23/RcppArmadillo/ChangeLog | 21 RcppArmadillo-0.2.23/RcppArmadillo/DESCRIPTION | 10 RcppArmadillo-0.2.23/RcppArmadillo/NAMESPACE | 14 RcppArmadillo-0.2.23/RcppArmadillo/R/fastLm.R | 22 RcppArmadillo-0.2.23/RcppArmadillo/inst/NEWS | 22 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo | 3 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/Cube_meat.hpp | 12 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/Mat_bones.hpp | 2 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp | 150 +++- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/arma_version.hpp | 4 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/auxlib_bones.hpp | 15 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/auxlib_meat.hpp | 352 +++++----- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/config.hpp | 8 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/debug.hpp | 224 ++++-- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/diskio_bones.hpp | 12 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/diskio_meat.hpp | 301 +++++++- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/field_meat.hpp | 18 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_chol.hpp | 30 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_eig.hpp | 84 +- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_inv.hpp | 36 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_log_det.hpp | 10 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_lu.hpp | 33 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_misc.hpp | 12 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_pinv.hpp | 33 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_princomp.hpp | 49 + RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_qr.hpp | 11 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_rank.hpp | 13 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_solve.hpp | 13 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_svd.hpp | 25 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/fn_syl_lyap.hpp | 18 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/forward_bones.hpp | 3 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/glue_join_meat.hpp | 71 +- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/glue_solve_meat.hpp | 13 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/lapack_bones.hpp | 95 ++ RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_chol_meat.hpp | 6 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_inv_bones.hpp | 6 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_inv_meat.hpp | 39 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_max_meat.hpp | 50 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_median_meat.hpp | 115 +-- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_min_meat.hpp | 50 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_misc_bones.hpp | 14 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_misc_meat.hpp | 46 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_pinv_meat.hpp | 39 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_princomp_bones.hpp | 20 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_princomp_meat.hpp | 248 ++----- RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_prod_meat.hpp | 34 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_stddev_meat.hpp | 38 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_sum_meat.hpp | 36 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/op_var_meat.hpp | 38 - RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/running_stat_meat.hpp | 4 RcppArmadillo-0.2.23/RcppArmadillo/inst/include/armadillo_bits/running_stat_vec_meat.hpp | 4 RcppArmadillo-0.2.23/RcppArmadillo/inst/unitTests/runit.fastLm.R | 8 RcppArmadillo-0.2.23/RcppArmadillo/man/fastLm.Rd | 32 RcppArmadillo-0.2.23/RcppArmadillo/src/fastLm.cpp | 15 57 files changed, 1695 insertions(+), 886 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The New York evening was organized by pianist Bill Charlap (wikipedia) who also headlined and MC-ed the first set. Covering the birth of Jazz until early post-war bebop in chronological fashion, it was a pretty decent jazz set with a very nice band featuring Kenny Washington (dr), Peter Washington (b), Jeremy Pelt (tp), Jimmy Greene (ts) and Ken Peplowski (cl) --- and local favourite Kurt Elling (wikipedia) who was simply outstanding with the classic songbook material. Having seen him live once before a few years ago, I happened to listen a lot to Elling of late, following the random find of this stream from a live concert in February as well as his two most recent records, the Grammy-winning Dedicated to You (which retakes the wonderful Coltrane/Hartman album from 1963) and the simply amazing very recent The Gate (which you should go and buy right now). And I was not disappointed. He has a great four-octave-spanning baritone voice and great stage presence.
The second set was dedicated to post-war folk and singer/songwriter material and organized by Suzanne Vega. That was neat too, if somewhat different in format and more like your standard (rock-ish) concert. Vega brought her own band featuring Gerry Leonard (g), Mike Visceglia (b), Graham Hawthorne (dr) along with guest appearances by Tom Paxton (g, vocals) and Richard Julian (g, vocals). Somehow Vega seems a little trapped in her own success in the 1980s and rehashed a lot of old hits. Nothing wrong that per se as it is good material (more on that below). Only during three encores did she provide new material which was ... excellent. So maybe some rebalancing towards new stuff was neat. Also nice was the additiona of four string players from the Chicago Symphony which had joined the band for a Simon and Garfunkel's song The Boxer. Oh, and of course seeing Vega perform Tom's Diner was nice, especially in such a fast and rocking version, even enhanced by the those strings. Just a few months ago I had gone over the passage from the original a-capella version of Tom's Diner to the various beat-box remixes which were then remixed by Vega in various live performances (e.g. videos of a capella, rockish, another rockish and beatboxish versions). Good fun, and it is nice to see she is playing along and enjoying it as well.
All told, a really nice iniative by the CSO. If you're in Chicagoland, go and see some of the remaining shows.
It was evident how much joy Charles Lloyd still gets from performing live at his somewhat advanced age of 73. Surrounded by some extraordinary musicians, and clearly enjoying himself on stage. Great evening with wonderful jazz music from somewhere in between modern post-whatever, free, bop and hard bop, world music and everything else in between. I regret not having seen him earlier in life. Very much recommended.
Thanks to a patch by Mario Frasca, digest now contains a
second (exported) function hmac()
to generate
Hash-based Message Authentication Code as defined in
RFC 2104. Reference output from RFC 2104 is used to validate
this functionality as shown below where we run the example code from the hmac()
help page:
R> library(digest) R> example(hmac) hmacR> ## Standard RFC 2104 test vectors hmacR> current <- hmac('Jefe', 'what do ya want for nothing?', "md5") hmacR> target <- '750c783e6ab0b503eaa86e310a5db738' hmacR> stopifnot(identical(target, as.character(current))) hmacR> current <- hmac(rep(0x0b, 16), 'Hi There', "md5") hmacR> target <- '9294727a3638bb1c13f48ef8158bfc9d' hmacR> stopifnot(identical(target, as.character(current))) hmacR> current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "md5") hmacR> target <- '56be34521d144c88dbb8c733f0e8b3f6' hmacR> stopifnot(identical(target, as.character(current))) hmacR> ## SHA1 tests inspired to the RFC 2104 and checked against the python hmacR> ## hmac implementation. hmacR> current <- hmac('Jefe', 'what do ya want for nothing?', "sha1") hmacR> target <- 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79' hmacR> stopifnot(identical(target, as.character(current))) hmacR> current <- hmac(rep(0x0b, 16), 'Hi There', "sha1") hmacR> target <- '675b0b3a1b4ddf4e124872da6c2f632bfed957e9' hmacR> stopifnot(identical(target, as.character(current))) hmacR> current <- hmac(rep(0xaa, 16), rep(0xdd, 50), "sha1") hmacR> target <- 'd730594d167e35d5956fd8003d0db3d3f46dc7bb' hmacR> stopifnot(identical(target, as.character(current))) R>
Also, CRANberries shows the difference to the previsious release 0.4.2 as follows:
Diff between digest versions 0.4.2 dated 2009-12-06 and 0.5.0 dated 2011-05-30 digest-0.4.2/digest/INDEX |only digest-0.4.2/digest/R/zzz.R |only digest-0.4.2/digest/inst |only digest-0.5.0/digest/ChangeLog |only digest-0.5.0/digest/DESCRIPTION | 33 ++++++++++++------------- digest-0.5.0/digest/NAMESPACE | 7 +++-- digest-0.5.0/digest/R/hmac.R |only digest-0.5.0/digest/man/hmac.Rd |only digest-0.5.0/digest/tests/digestTest.Rout.save | 2 - digest-0.5.0/digest/tests/hmacTest.R |only digest-0.5.0/digest/tests/hmacTest.Rout.save |only 11 files changed, 22 insertions(+), 20 deletions(-)
With that, special thanks to Mario Frasca for the patch and to Henrik Bengtsson for helpful discussion. We took some care to ensure that the
existing interface to the digest()
function remains unaffected.
The short NEWS file extract follows below.
And courtesy of CRANberries, here is the diff to the previous release.0.2.21 2011-05-27 o Upgraded to Armadillo release 1.99.3 "v2.0 beta 3" * stricter size checking for row and column vectors * added .count() member function to running_stat and running_stat_vec
Diff between RcppArmadillo versions 0.2.20 dated 2011-05-26 and 0.2.21 dated 2011-05-28 ChangeLog | 8 DESCRIPTION | 8 inst/NEWS | 7 inst/include/armadillo | 2 inst/include/armadillo_bits/Col_meat.hpp | 13 - inst/include/armadillo_bits/Mat_bones.hpp | 2 inst/include/armadillo_bits/Mat_meat.hpp | 147 +++++++------- inst/include/armadillo_bits/Row_meat.hpp | 11 - inst/include/armadillo_bits/arma_version.hpp | 4 inst/include/armadillo_bits/diagview_bones.hpp | 2 inst/include/armadillo_bits/diagview_meat.hpp | 4 inst/include/armadillo_bits/diskio_meat.hpp | 40 ++-- inst/include/armadillo_bits/fn_accu.hpp | 167 ++++++++++------- inst/include/armadillo_bits/fn_det.hpp | 10 - inst/include/armadillo_bits/fn_prod.hpp | 15 + inst/include/armadillo_bits/op_dot_bones.hpp | 9 inst/include/armadillo_bits/op_dot_meat.hpp | 119 +++++++++--- inst/include/armadillo_bits/promote_type.hpp | 24 +- inst/include/armadillo_bits/running_stat_bones.hpp | 16 - inst/include/armadillo_bits/running_stat_meat.hpp | 47 ++-- inst/include/armadillo_bits/running_stat_vec_bones.hpp | 6 inst/include/armadillo_bits/running_stat_vec_meat.hpp | 21 +- inst/include/armadillo_bits/subview_meat.hpp | 23 +- inst/include/armadillo_bits/traits.hpp | 16 - inst/include/armadillo_bits/typedef_u64.hpp | 21 -- 25 files changed, 446 insertions(+), 296 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The race went ok -- I didn't go out too fast, maintained pace and was able to accelerate towards the end. My hand-stopped time was 22:58; for the first time we actually had chip timing in this race and my official time appears to be 23:00. Which is still 50+ seconds faster than last year, and a pace of around 6:34 and compares well to the other eight previous times I've run this.
Also added in this version is a new example of a simulation of a vector autoregression process which I had blogged about earlier. The example had been prepared for the Rcpp workshop / class at last month's R/Finance conference, and demonstrates a rather nice speed gain from using Rcpp and RcppArmadillo.
The short NEWS file extract follows below.
And courtesy of CRANberries, here is the diff to the previous release.0.2.20 2011-05-25 o Upgraded to Armadillo release 1.99.2 "v2.0 beta 2" (and 1.99.1 before) * faster inverse of symmetric matrices * faster element access for fixed size matrices * faster multiplication of tiny matrices (eg. 4x4) * faster compund expressions containing submatrices * added handling of arbitrarily sized empty matrices (eg. 5x0) * added syl() * added strans() * added symmatu()/symmatl() * added submatrices of submatrices * htrans() has been deprecated; use trans() instead * trans() now takes the complex conjugate when transposing a complex matrix * .is_vec() now outputs true for empty matrices * most functions with matrix inputs no longer throw exceptions when given empty matrices (eg. 5x0) o Added a new subdirectory examples/ seeded with a nice Vector Autoregression simulation simulation example by Lance Bachmeier o Rewrote armadillo_version as to no longer require an instance of arma::arma_version, with tanks to Conrad for the suggestion
Diff between RcppArmadillo versions 0.2.19 dated 2011-04-24 and 0.2.20 dated 2011-05-26 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Col_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Cube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/GlueCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Glue_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Mat_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/OpCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Op_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/Row_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/arrayops_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/atlas_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/auxlib_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/blas_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/diagview_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/diskio_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eGlueCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eGlue_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eOpCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eOp_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eglue_core_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/eop_core_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/field_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/fn_htrans.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/forward_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_conv_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_cor_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_cov_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_cross_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_join_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_kron_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_mixed_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_relational_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_solve_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_times_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/glue_toeplitz_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/injector_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/lapack_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/mtGlueCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/mtGlue_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/mtOpCube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/mtOp_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_chol_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_cor_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_cov_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_cumsum_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_cx_scalar_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_diagmat_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_diagvec_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_dot_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_dotext_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_find_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_flip_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_htrans_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_inv_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_max_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_mean_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_median_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_min_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_misc_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_pinv_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_princomp_cov_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_princomp_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_prod_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_relational_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_repmat_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_reshape_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_shuffle_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_sort_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_stddev_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_sum_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_trans_meat.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_trans_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_trimat_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/op_var_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/podarray_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/running_stat_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/running_stat_vec_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/subview_cube_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/subview_elem1_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/subview_field_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/subview_proto.hpp |only RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/wall_clock_proto.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/ChangeLog | 20 RcppArmadillo-0.2.20/RcppArmadillo/DESCRIPTION | 10 RcppArmadillo-0.2.20/RcppArmadillo/inst/NEWS | 26 RcppArmadillo-0.2.20/RcppArmadillo/inst/examples |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/RcppArmadillo/Mat_meat.h | 8 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo | 199 - RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Col_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Col_meat.hpp | 519 +++ RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Cube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Cube_meat.hpp | 96 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/GlueCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Glue_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Mat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp | 673 +++- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/OpCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Op_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Proxy.hpp | 28 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/ProxyCube.hpp | 20 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Row_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/Row_meat.hpp | 491 +++ RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_meat.hpp | 87 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arma_static_assert.hpp | 31 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arma_version.hpp | 6 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arrayops_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/arrayops_meat.hpp | 143 - RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/atlas_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/auxlib_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/auxlib_meat.hpp | 772 ++++- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/blas_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/compiler_setup.hpp | 17 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/debug.hpp | 24 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/diagmat_proxy.hpp | 93 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/diagview_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/diagview_meat.hpp | 128 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/diskio_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/diskio_meat.hpp | 104 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eGlueCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eGlueCube_meat.hpp | 14 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eGlue_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eGlue_meat.hpp | 14 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eOpCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eOp_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eglue_core_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eglue_core_meat.hpp | 519 ++- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eop_core_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/eop_core_meat.hpp | 327 +- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/field_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_accu.hpp | 40 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_det.hpp | 7 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_diagmat.hpp | 7 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_elem.hpp | 62 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_eye.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_inv.hpp | 18 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_log_det.hpp | 8 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_max.hpp | 38 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_mean.hpp | 42 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_median.hpp | 53 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_min.hpp | 38 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_ones.hpp | 45 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_prod.hpp | 20 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_randn.hpp | 10 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_randu.hpp | 12 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_stddev.hpp | 20 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_strans.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_syl_lyap.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_symmat.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_trans.hpp | 35 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_var.hpp | 20 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/fn_zeros.hpp | 12 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/forward_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/gemm.hpp | 337 -- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/gemm_mixed.hpp | 59 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/gemv.hpp | 208 + RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_conv_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_conv_meat.hpp | 16 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_cor_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_cor_meat.hpp | 12 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_cov_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_cross_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_cross_meat.hpp | 47 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_join_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_join_meat.hpp | 46 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_kron_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_mixed_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_relational_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_solve_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_times_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_times_meat.hpp | 493 +-- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_toeplitz_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/glue_toeplitz_meat.hpp | 5 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/injector_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/lapack_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/mtGlueCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/mtGlue_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/mtOpCube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/mtOp_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_chol_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cor_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cor_meat.hpp | 14 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cov_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cumsum_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cumsum_meat.hpp | 9 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_cx_scalar_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_diagmat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_diagmat_meat.hpp | 10 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_diagvec_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_dot_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_dotext_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_find_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_flip_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_htrans_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_htrans_meat.hpp | 98 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_inv_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_inv_meat.hpp | 13 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_max_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_max_meat.hpp | 57 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_mean_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_mean_meat.hpp | 34 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_median_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_median_meat.hpp | 214 - RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_min_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_min_meat.hpp | 33 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_misc_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_pinv_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_pinv_meat.hpp | 10 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_princomp_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_princomp_cov_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_prod_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_prod_meat.hpp | 34 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_relational_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_repmat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_repmat_meat.hpp | 29 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_reshape_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_reshape_meat.hpp | 32 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_shuffle_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_shuffle_meat.hpp | 10 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_sort_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_stddev_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_stddev_meat.hpp | 34 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_strans_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_strans_meat.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_sum_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_sum_meat.hpp | 38 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_symmat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_symmat_meat.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_trimat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_trimat_meat.hpp | 190 + RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_var_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/op_var_meat.hpp | 37 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/operator_times.hpp | 12 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/podarray_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/podarray_meat.hpp | 57 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/promote_type.hpp | 18 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/running_stat_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/running_stat_meat.hpp | 2 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/running_stat_vec_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_cube_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_cube_meat.hpp | 50 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_elem1_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_elem1_meat.hpp | 24 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_field_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_field_meat.hpp | 37 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/subview_meat.hpp | 1423 +++++++++- RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/traits.hpp | 69 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/typedef_u64.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/undefine_conflicts.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/unwrap.hpp | 64 RcppArmadillo-0.2.20/RcppArmadillo/inst/include/armadillo_bits/wall_clock_bones.hpp |only RcppArmadillo-0.2.20/RcppArmadillo/src/RcppArmadillo.cpp | 27 253 files changed, 6400 insertions(+), 2358 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The organizing committee for the R/Finance 2011 conference is pleased to announce the availability of presentation slides from the 3rd annual R/Finance conference. This year's two-day conference once again attracted over 200 participants from across the globe. Academics, students and industry professionals enjoyed almost 30 talks covering trading, optimization, risk management and more --- all using R!The majority of these presentations are now available for download at:
http://www.RinFinance.com/agenda/This year we began offering prizes for the best paper submissions. The 2011 recipients are Robert Gramacy (University of Chicago) and David Matteson (Cornell University) who each won USD 1000. Also new was a graduate student travel award: Mikko Niemenmaa (Aalto University) and Clément Dunand-Châtellet (École Polytechnique) each received USD 500.With this, the organizing committee would like to thank our lead conference sponsors, the International Center for Futures and Derivatives at UIC and Revolution Analytics, as well as our conference sponsors OneMarketData, RStudio and Lemnica for their continued support.
The organising committee would also like to thank all of the presenters and participants for making R/Finance 2011 so successful. We look forward to seeing you in 2012, with the prospective dates of May 17 - 19 to be confirmed.
For the organizing committee,
Gib Bassett, Peter Carl, Dirk Eddelbuettel, Brian Peterson,
Dale Rosenthal, Jeffrey Ryan, Joshua Ulrich
Enjoy!
Update: One link corrected.
This new release contains a few small internal changes to the initialization
code, as well as a number of slightly improved examples employing more of the
simplifications which Rcpp offers.
Also included is a brand new example embedding R
inside of the Qt framework; an
earlier blog post
had already discussed this example. Two more examples were added to the
standard/examples
directory which now contains fourteen plus two tests.
We also added a NEWS file, the entry for this release is below.
And courtesy of CRANberries, here are the changes from the previous release.0.2.4 2011-04-24 o Minor code cleanups in initialization code o New example embedding R inside a Qt application, along with pro file for Qt's qmake providing a complete simple C++ GUI application o New examples rinside_sample{10,11} based on questions on the r-help and r-devel mailing list o Some improvements and simplifications throughout examples/standard as well as examples/mpi/ o Added this NEWS files -- with entries below summarised from ChangeLog and the corresponding blog posts
RInside-0.2.3/RInside/inst/ChangeLog |only RInside-0.2.3/RInside/libRInside.a |only RInside-0.2.4/RInside/ChangeLog |only RInside-0.2.4/RInside/DESCRIPTION | 24 ++++-- RInside-0.2.4/RInside/R/RInsidePaths.R | 4 - RInside-0.2.4/RInside/doxyfile | 8 +- RInside-0.2.4/RInside/inst/NEWS |only RInside-0.2.4/RInside/inst/THANKS | 1 RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample0.cpp | 10 +- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample1.cpp | 11 +-- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample2.cpp | 10 +- RInside-0.2.4/RInside/inst/examples/mpi/rinside_mpi_sample3.cpp | 9 -- RInside-0.2.4/RInside/inst/examples/qt |only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample1.cpp | 30 ++++---- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample10.cpp |only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample11.cpp |only RInside-0.2.4/RInside/inst/examples/standard/rinside_sample2.cpp | 15 +--- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample3.cpp | 6 - RInside-0.2.4/RInside/inst/examples/standard/rinside_sample5.cpp | 10 +- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample6.cpp | 12 +-- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample7.cpp | 9 -- RInside-0.2.4/RInside/inst/examples/standard/rinside_sample9.cpp | 2 RInside-0.2.4/RInside/inst/include/RInsideAutoloads.h | 35 ++++++++-- RInside-0.2.4/RInside/inst/include/RInsideEnvVars.h | 13 +-- RInside-0.2.4/RInside/src/Makevars | 2 RInside-0.2.4/RInside/src/RInside.cpp | 21 +++--- 26 files changed, 121 insertions(+), 111 deletions(-)
More information is on the RInside page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The short NEWS file extract follows below containing just Conrad's entry for 1.2.0. No further changes from our side (and the benchmark comparison between R, compiled R and Rcpp for computing a VAR(1) dataset which I blogged about yesterday is only in SVN and will be in the next release.)
And courtesy of CRANberries, here are the diffs to the previous release.0.2.19 2011-04-18 o Upgraded to Armadillo version 1.2.0 "Unscrupulous Carbon Emitter" * Added ability to use Blas & Lapack libraries with capitalised function names * Reduction of pedantic compiler warnings
RcppArmadillo-0.2.18/RcppArmadillo/inst/doc/RcppArmadillo-unitTests.tex |only RcppArmadillo-0.2.19/RcppArmadillo/ChangeLog | 10 RcppArmadillo-0.2.19/RcppArmadillo/DESCRIPTION | 10 RcppArmadillo-0.2.19/RcppArmadillo/R/fastLm.R | 2 RcppArmadillo-0.2.19/RcppArmadillo/inst/NEWS | 22 RcppArmadillo-0.2.19/RcppArmadillo/inst/doc/Makefile | 5 RcppArmadillo-0.2.19/RcppArmadillo/inst/doc/RcppArmadillo-unitTests.pdf |binary RcppArmadillo-0.2.19/RcppArmadillo/inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 16 RcppArmadillo-0.2.19/RcppArmadillo/inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 40 - RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_meat.hpp | 14 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/arma_ostream_proto.hpp | 4 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/arma_version.hpp | 6 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/auxlib_meat.hpp | 128 +-- RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/blas_proto.hpp | 92 +- RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/compiler_setup.hpp | 12 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/config.hpp | 3 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/constants.hpp | 20 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/diskio_meat.hpp | 2 RcppArmadillo-0.2.19/RcppArmadillo/inst/include/armadillo_bits/lapack_proto.hpp | 344 ++++++---- 19 files changed, 460 insertions(+), 270 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
And I received a few friendly answers. My favourite, so far, was a suggestion by Lance Bachmeier who sent me a short script which used both R and C++ (via Rcpp) to simulate a first-order vector autoregressive process (and he ensured me that it worked well enough on his graduate students). It is indeed a great example as it involves (simple) matrix multiplication in an iterative fashion. Which makes it a great example not only for Rcpp but also for our RcppArmadillo package (which wraps Conrad Sanderson's wonderful Armadillo C++ templated library for linear algebra and more). And at the same time, we can also add another look at the new and shiny R compiler I also blogged about recently.
So Lance and I iterated over this a little more over email, and I now added this as a new (and initial) example file in the RcppArmadillo SVN repo. (As an aside: The newest version 0.2.19 of RcppArmadillo has been sitting in incoming at CRAN since earlier in the week while the archive maintainer takes a well-deserved vacation. It should hit the public archive within a few days, and is otherwise available too from my site.)
So let's walk through the example:
This starts with a simple enough loop. After skipping the first row, each iteration multiplies the previous row with the parameters and adds error terms.R> ## parameter and error terms used throughout R> a <- matrix(c(0.5,0.1,0.1,0.5),nrow=2) R> e <- matrix(rnorm(10000),ncol=2) R> ## Let's start with the R version R> rSim <- function(coeff, errors) { + simdata <- matrix(0, nrow(errors), ncol(errors)) + for (row in 2:nrow(errors)) { + simdata[row,] = coeff %*% simdata[(row-1),] + errors[row,] + } + return(simdata) + } R> rData <- rSim(a, e) # generated by R
We can then turn to the R compiler:
Nice and easy: We load the compiler package, create a compiled function and use it. We check the results and surely enough find them to be identical.R> ## Now let's load the R compiler (requires R 2.13 or later) R> suppressMessages(require(compiler)) R> compRsim <- cmpfun(rSim) R> compRData <- compRsim(a,e) # generated by R 'compiled' R> stopifnot(all.equal(rData, compRData)) # checking results
With that, time to turn to C++ using Armadillo via RcppArmadillo:
Here we load the inline package to compile, link and load C++ snippets. We define a short C++ function in theR> ## Now load 'inline' to compile C++ code on the fly R> suppressMessages(require(inline)) R> code <- ' + arma::mat coeff = Rcpp::as<arma::mat>(a); + arma::mat errors = Rcpp::as<arma::mat>(e); + int m = errors.n_rows; int n = errors.n_cols; + arma::mat simdata(m,n); + simdata.row(0) = arma::zeros<arma::mat>(1,n); + for (int row=1; row<m; row++) { + simdata.row(row) = simdata.row(row-1)*trans(coeff)+errors.row(row); + } + return Rcpp::wrap(simdata); + ' R> ## create the compiled function R> rcppSim <- cxxfunction(signature(a="numeric",e="numeric"), + code,plugin="RcppArmadillo") R> rcppData <- rcppSim(a,e) # generated by C++ code R> stopifnot(all.equal(rData, rcppData)) # checking results
code
variable, declare a signature taking a
and e
as before and ask
cxxfunction()
to deploy the plugin for RcppArmadillo so
that it and Rcpp are found during build. With that, we have a compiled function
to generate data, and we once again check the result. The C++ code is pretty straightforward as well. We can instatiate Armadillo matrices
directly from the R objects we pass down; we then run a similar loop building the result row by row.
Now, with all the build-up, here is the final timing comparison, using the rbenchmark package:
So in a real-world example involving looping and some algebra (which is of course already done by BLAS and LAPACK libraries), the new R compiler improves by more than a factor of two, cutting time from 4.14 seconds down to about 2 seconds. Yet, this still leaves the C++ solution, clocking in at a mere 38 milliseconds, ahead by a factor of over fifty relative to the new R compilerR> ## now load the rbenchmark package and compare all three R> suppressMessages(library(rbenchmark)) R> res <- benchmark(rcppSim(a,e), + rSim(a,e), + compRsim(a,e), + columns=c("test", "replications", "elapsed", + "relative", "user.self", "sys.self"), + order="relative") R> print(res) test replications elapsed relative user.self sys.self 1 rcppSim(a, e) 100 0.038 1.0000 0.04 0 3 compRsim(a, e) 100 2.011 52.9211 2.01 0 2 rSim(a, e) 100 4.148 109.1579 4.14 0
And compared to just R itself, the simple solution involving Rcpp and RcppArmadillo is almost 110 times faster. As I mentioned, I quite like this example ;-).
This version contains an improvement to loading and initialization of Rcpp modules, a bug fix for vectors of factors, another build issue fix as well as (per common practice with JSS) citation information for the article Rcpp: Seamless R and C++ Integration which is now Volume 40, Issue 8 in the Journal of Statistical Software (or JSS for short).
The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, there is also a diff to the previous release 0.9.3:0.9.4 2011-04-12 o New R function "loadRcppModules" to load Rcpp modules automatically from a package. This function must be called from the .onLoad function and works with the "RcppModules" field of the package's DESCRIPTION file o The Modules example wrapped the STL std::vector received some editing to disambiguate some symbols the newer compilers did not like o Coercing of vectors of factors is now done with an explicit callback to R's "as.character()" as Rf_coerceVector no longer plays along o A CITATION file for the published JSS paper has been added, and references were added to Rcpp-package.Rd and the different vignettes
Diff between Rcpp versions 0.9.3 dated 2011-04-05 and 0.9.4 dated 2011-04-12 Rcpp-0.9.3/Rcpp/build |only Rcpp-0.9.3/Rcpp/inst/skeleton/yada.Rd |only Rcpp-0.9.3/Rcpp/inst/unitTests/testRcppModule/R/Modules.R |only Rcpp-0.9.3/Rcpp/inst/unitTests/testRcppModule/man/yada.Rd |only Rcpp-0.9.4/Rcpp/ChangeLog | 55 Rcpp-0.9.4/Rcpp/DESCRIPTION | 10 Rcpp-0.9.4/Rcpp/NAMESPACE | 29 Rcpp-0.9.4/Rcpp/R/Rcpp.package.skeleton.R | 11 Rcpp-0.9.4/Rcpp/R/loadRcppModules.R |only Rcpp-0.9.4/Rcpp/inst/CITATION |only Rcpp-0.9.4/Rcpp/inst/NEWS | 17 Rcpp-0.9.4/Rcpp/inst/doc/Makefile | 2 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-FAQ.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-FAQ/Rcpp-FAQ.Rnw | 153 +- Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-extending.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-extending/Rcpp-extending.Rnw | 2 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-introduction.Rnw | 734 ++++------ Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-introduction.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-modules.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-modules/Rcpp-modules.Rnw | 36 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-package.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-package/Rcpp-package.Rnw | 4 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-quickref.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-quickref/Rcpp-quickref.Rnw | 34 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-sugar.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-sugar/Rcpp-sugar.Rnw | 2 Rcpp-0.9.4/Rcpp/inst/doc/Rcpp-unitTests.pdf |binary Rcpp-0.9.4/Rcpp/inst/doc/Rcpp.bib | 73 Rcpp-0.9.4/Rcpp/inst/doc/unitTests-results/Rcpp-unitTests.html | 18 Rcpp-0.9.4/Rcpp/inst/doc/unitTests-results/Rcpp-unitTests.txt | 40 Rcpp-0.9.4/Rcpp/inst/include/Rcpp/config.h | 2 Rcpp-0.9.4/Rcpp/inst/skeleton/zzz.R | 11 Rcpp-0.9.4/Rcpp/inst/unitTests/runit.Module.client.package.R | 27 Rcpp-0.9.4/Rcpp/inst/unitTests/runit.Vector.R | 18 Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/DESCRIPTION | 2 Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/NAMESPACE | 3 Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/R/zzz.R |only Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/src/rcpp_module.cpp | 6 Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/src/stdVector.cpp | 18 Rcpp-0.9.4/Rcpp/inst/unitTests/testRcppModule/tests/modules.R | 21 Rcpp-0.9.4/Rcpp/man/Rcpp-package.Rd | 6 Rcpp-0.9.4/Rcpp/man/loadRcppModules.Rd |only Rcpp-0.9.4/Rcpp/src/r_cast.cpp | 9 43 files changed, 647 insertions(+), 696 deletions(-)
As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page
The NEWS file entry follows below:
And courtesy of CRANberries, here is the diff to the previous release 0.2.2:0.2.3 2011-04-12 o Protect UINT64 and INT64 with '#ifdef RCPP_HAS_LONG_LONG' which itself is valid with either g++ <= 4.4, or newer versions if the -std=c++0x is used o The documentation Makefile now uses the $R_HOME environment variable o The documentation Makefile no longer calls clean in the all target
Diff between RProtoBuf versions 0.2.2 dated 2011-01-12 and 0.2.3 dated 2011-04-13 RProtoBuf-0.2.2/RProtoBuf/inst/doc/RProtoBuf-quickref.Rnw |only RProtoBuf-0.2.3/RProtoBuf/ChangeLog | 23 RProtoBuf-0.2.3/RProtoBuf/DESCRIPTION | 8 RProtoBuf-0.2.3/RProtoBuf/R/with.R | 12 RProtoBuf-0.2.3/RProtoBuf/cleanup | 3 RProtoBuf-0.2.3/RProtoBuf/inst/NEWS | 10 RProtoBuf-0.2.3/RProtoBuf/inst/doc/Makefile | 42 RProtoBuf-0.2.3/RProtoBuf/inst/doc/RProtoBuf-quickref.pdf |binary RProtoBuf-0.2.3/RProtoBuf/inst/doc/RProtoBuf-unitTests.pdf |binary RProtoBuf-0.2.3/RProtoBuf/inst/doc/RProtoBuf.pdf | 1267 +++++----- RProtoBuf-0.2.3/RProtoBuf/inst/doc/unitTests-results/RProtoBuf-unitTests.html | 20 RProtoBuf-0.2.3/RProtoBuf/inst/doc/unitTests-results/RProtoBuf-unitTests.txt | 14 RProtoBuf-0.2.3/RProtoBuf/src/extractors.cpp | 44 RProtoBuf-0.2.3/RProtoBuf/src/mutators.cpp | 55 RProtoBuf-0.2.3/RProtoBuf/src/wrapper_FieldDescriptor.cpp | 24 15 files changed, 819 insertions(+), 703 deletions(-)
As always, there is more information at the RProtoBuf page which has a draft package vignette, a 'quick' overview vignette and a unit test summary vignette. Questions, comments etc should go to the rprotobuf mailing list off the RProtoBuf page at R-Forge.
so the compiler is not yet used for R's own base and recommended packages.o Package compiler is now provided as a standard package. See ?compiler::compile for information on how to use the compiler. This package implements a byte code compiler for R: by default the compiler is not used in this release. See the 'R Installation and Administration Manual' for how to compile the base and recommended packages.
While working on my slides for the upcoming Rcpp workshop preceding R/Finance 2011, I thought of a nice test example to illustrate the compiler. Last summer and fall, Radford Neal had sent a very nice, long and detailed list of possible patches for R performance improvements to the development list. Some patches were integrated and some more discussion ensued. One strand was on the difference in parsing between normal parens and curly braces. In isolation, these seem too large, but (as I recall) this is due some things 'deep down' in the parser.
However, some folks really harped on this topic. And it just doesn't die as a post from last week demonstrated once more. Last year, Christian Robert had whittled it down to a set of functions, and I made a somewhat sarcastic post argueing that I'd rather use Rcpp to get 80-fold speed increase than spend my time argueing over ten percent changes in code that could be made faster so easily.
So let us now examine what the compiler package can do for us. The starting point is the same as last year: five variants
of computing 1/(1+x) for a scalar x inside an explicit for
loop. Real code would never do it this way as vectorisation comes
to the rescue. But for (Christian's) argument's sake, it is useful to highlight differences in the parser. We once again use
the nice rbenchmark package to run, time and summarise alternatives:
This replicates Christian's result. We find that function> ## cf http://dirk.eddelbuettel.com/blog/2010/09/07#straight_curly_or_compiled > f <- function(n, x=1) for (i in 1:n) x=1/(1+x) > g <- function(n, x=1) for (i in 1:n) x=(1/(1+x)) > h <- function(n, x=1) for (i in 1:n) x=(1+x)^(-1) > j <- function(n, x=1) for (i in 1:n) x={1/{1+x}} > k <- function(n, x=1) for (i in 1:n) x=1/{1+x} > ## now load some tools > library(rbenchmark) > ## now run the benchmark > N <- 1e6 > benchmark(f(N,1), g(N,1), h(N,1), j(N,1), k(N,1), + columns=c("test", "replications", + "elapsed", "relative"), + order="relative", replications=10) test replications elapsed relative 5 k(N, 1) 10 9.764 1.00000 1 f(N, 1) 10 9.998 1.02397 4 j(N, 1) 10 11.019 1.12853 2 g(N, 1) 10 11.822 1.21077 3 h(N, 1) 10 14.560 1.49119
k()
is the fastest using curlies, and that explicit exponentiation in
function h()
is the slowest with a relative penalty of 49%, or an absolute difference of almost five seconds between the 9.7
for the winner and 14.6 for the worst variant. On the other hand, function f()
, the normal way of writing things, does pretty
well.
So what happens when we throw the compiler into the mix? Let's first create compiled variants using the new cmpfun()
function and then try again:
Now things have gotten interesting and substantially faster, for very little cost. Usage is straightforward: take your function and compile it, and reap more than a threefold speed gain. Not bad at all. Also of note, the difference between the different expressions essentially vanishes. The explicit exponentiation is still the loser, but there may be an additional explicit function call involved.> ## R 2.13.0 brings this toy > library(compiler) > lf <- cmpfun(f) > lg <- cmpfun(g) > lh <- cmpfun(h) > lj <- cmpfun(j) > lk <- cmpfun(k) > # now run the benchmark > N <- 1e6 > benchmark(f(N,1), g(N,1), h(N,1), j(N,1), k(N,1), + lf(N,1), lg(N,1), lh(N,1), lj(N,1), lk(N,1), + columns=c("test", "replications", + "elapsed", "relative"), + order="relative", replications=10) test replications elapsed relative 9 lj(N, 1) 10 2.971 1.00000 10 lk(N, 1) 10 2.980 1.00303 6 lf(N, 1) 10 2.998 1.00909 7 lg(N, 1) 10 3.007 1.01212 8 lh(N, 1) 10 4.024 1.35443 1 f(N, 1) 10 9.479 3.19051 5 k(N, 1) 10 9.526 3.20633 4 j(N, 1) 10 10.775 3.62673 2 g(N, 1) 10 11.299 3.80310 3 h(N, 1) 10 14.049 4.72871
So we do see the new compiler as a potentially very useful addition. I am sure more folks will jump on this and run more
tests to find clearer corner cases. To finish, we have to of course once more go back to
Rcpp for some
Rcpp still shoots the lights out by a factor of 80 (or even almost 120 to the worst manual implementation) relative to interpreted code. Relative to the compiled byte code, the speed difference is about 25-fold. Now, these are of course entirely unrealistic code examples that are in no way, shape or form representative of real R work. Effective speed gains will be smaller for both the (pretty exciting new) compiler package and also for our C++ integration package Rcpp.> ## now with Rcpp and C++ > library(inline) > ## and define our version in C++ > src <- 'int n = as<int>(ns); + double x = as<double>(xs); + for (int i=0; i<n; i++) x=1/(1+x); + return wrap(x); ' > l <- cxxfunction(signature(ns="integer", + xs="numeric"), + body=src, plugin="Rcpp") > ## now run the benchmark again > benchmark(f(N,1), g(N,1), h(N,1), j(N,1), k(N,1), + l(N,1), + lf(N,1), lg(N,1), lh(N,1), lj(N,1), lk(N,1), + columns=c("test", "replications", + "elapsed", "relative"), + order="relative", replications=10) test replications elapsed relative 6 l(N, 1) 10 0.120 1.0000 11 lk(N, 1) 10 2.961 24.6750 7 lf(N, 1) 10 3.128 26.0667 8 lg(N, 1) 10 3.140 26.1667 10 lj(N, 1) 10 3.161 26.3417 9 lh(N, 1) 10 4.212 35.1000 5 k(N, 1) 10 9.500 79.1667 1 f(N, 1) 10 9.621 80.1750 4 j(N, 1) 10 10.868 90.5667 2 g(N, 1) 10 11.409 95.0750 3 h(N, 1) 10 14.077 117.3083
Before I close, two more public service announcements. First, if you use Ubuntu see this post by Michael on r-sig-debian announcing his implementation of a suggestion of mine: we now have R alpha/beta/rc builds via his Launchpad PPA. Last Friday, I had the current R-rc snapshot of R 2.13.0 on my Ubuntu box only about six hours after I (as Debian maintainer for R) uploaded the underlying new R-rc package build to Debian unstable. This will be nice for testing of upcoming releases. Second, as I mentioned, the Rcpp workshop on April 28 preceding R/Finance 2011 on April 29 and 30 still has a few slots available, as has the conference itself.
It contains no new code, but smoothes one or two edges in the build process
and noticed by the newest versions of
R CMD check
, just like
yesterday's RcppGSL release.
Courtesy of CRANberries, here are the changes to the previous release.
Diff between RcppClassic versions 0.9.0 dated 2010-12-20 and 0.9.1 dated 2011-04-07 RcppClassic-0.9.0/RcppClassic/build |only RcppClassic-0.9.0/RcppClassic/inst/lib |only RcppClassic-0.9.1/RcppClassic/ChangeLog | 17 ++++++ RcppClassic-0.9.1/RcppClassic/DESCRIPTION | 8 +-- RcppClassic-0.9.1/RcppClassic/inst/doc/Makefile | 25 ++++++---- RcppClassic-0.9.1/RcppClassic/inst/doc/RcppClassic-unitTests.pdf |binary RcppClassic-0.9.1/RcppClassic/inst/doc/RcppClassic.pdf |binary RcppClassic-0.9.1/RcppClassic/inst/doc/unitTests-results/RcppClassic-unitTests.html |only RcppClassic-0.9.1/RcppClassic/inst/doc/unitTests-results/RcppClassic-unitTests.txt |only RcppClassic-0.9.1/RcppClassic/inst/unitTests/runit.RcppDate.R | 24 ++++----- 10 files changed, 49 insertions(+), 25 deletions(-)
Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
I realized I never announced this on the blog, so without further ado....
This year's R/Finance conference will be preceded by a full-day masterclass on Rcpp and related topics which will be held on Thursday, April 28, 2011, on the University of Illinois at Chicago campus.
Join Dirk Eddelbuettel and Romain Francois for six hours of detailed and hands-on instructions and discussions around Rcpp, inline, RInside, RcppArmadillo and other packages---in an intimate small-group setting.
The full-day format allows to combine a morning introductory session with a more advanced afternoon session while leaving room for sufficient breaks. There will be about six hours of instructions, a one-hour lunch break and two half-hour coffee breaks.
The morning session will provide a practical introduction to the Rcpp package (and other related packages). The focus will be on simple and straightforward applications of Rcpp in order to extend R and/or to significantly accelerate the execution of simple functions.
The tutorial will cover the inline package which permits embedding of self-contained C, C++ or Fortran code in R scripts. We will also discuss RInside to embed R code in C++ applications, as well as standard Rcpp extension packages such as RcppArmadillo for linear algebra and RcppGSL.
This afternoon tutorial will provide a hands-on introduction to more advanced Rcpp features. It will cover topics such as writing packages that use Rcpp, how 'Rcpp modules' and the new R ReferenceClasses interact, and how 'Rcpp sugar' lets us write C++ code that is often as expressive as R code. Another possible topic, time permitting, may be writing glue code to extend Rcpp to other C++ projects.
We also hope to leave some time to discuss problems brought by the class participants.
Knowledge of R as well as general programming knowledge; C or C++ knowledge is helpful but not required.
Users should bring a laptop set up so that R packages can be built. That means on Windows, Rtools needs to be present and working, and on OS X the Xcode package should be installed.
Registration is available via the R/Finance conference at
http://www.RinFinance.com/register/
or directly at RegOnline
http://www.regonline.com/930153
The cost is USD 500 for the whole day, and space will be limited.
Please contact us directly at RomainAndDirk@r-enthusiasts.com.
It contains no new code, but smoothes one or two edges in the build process
and noticed by the newest versions of
R CMD check
. It also adds vignette from the unit tests as some
of our other packages do.
The short NEWS file extract follows below.
And courtesy of CRANberries, here are the changes to the previous release.0.1.1 2011-04-05 o Unit tests produce a summary vignette as for some of the other packages o The documentation Makefile now uses the $R_HOME environment variable o The documentation Makefile no longer calls clean in the all target
Diff between RcppGSL versions 0.1.0 dated 2010-12-01 and 0.1.1 dated 2011-04-06 ChangeLog | 22 ++++++++++++++++++++ DESCRIPTION | 8 +++---- inst/NEWS | 8 +++++++ inst/doc/Makefile | 28 ++++++++++++++++++++------ inst/doc/RcppGSL-unitTests.Rnw |only inst/doc/RcppGSL-unitTests.pdf |only inst/doc/RcppGSL-unitTests.tex |only inst/doc/RcppGSL.pdf |binary inst/doc/RcppGSL/RcppGSL.Rnw | 43 ++++++++++++++++++----------------------- inst/doc/unitTests |only src/Makevars.in | 2 - 11 files changed, 75 insertions(+), 36 deletions(-)
More information is on the RcppGSL page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
This version contains an actual bug fix for Rcpp modules and a few build improvements, including for both clang/llvm and g++-4.6 (which, being in Debian, is already used for conformance checks on CRAN's incoming directory) and g++-4.5. We also updated the main introductory vignette Rcpp-introduction to the content of what should be a forthcoming paper in the Journal of Statistical Software. The complete NEWS entry is below; more details are in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, there is also a diff to the previous release 0.9.2:0.9.3 2011-04-05 o Fixed a bug in which modules code was not behaving when compiled twice as can easily happen with inline'ed version o Exceptions code includes exception_defines.h only when g++ is 4.5 or younger as the file no longer exists with g++-4.6 o The documentation Makefile now uses the $R_HOME environment variable o The documentation Makefile no longer calls clean in the all target o C++ conformance issue found by clang/llvm addressed by re-ordering declarations in grow.h as unqualified names must be declared before they are used, even when used within templates o The 'long long' typedef now depends on C++0x being enabled as this was not a feature in C++98; this suppresses a new g++-4.5 warning o The Rcpp-introduction vignette was updated to the forthcoming JSS paper
Diff between Rcpp versions 0.9.2 dated 2011-02-24 and 0.9.3 dated 2011-04-05 ChangeLog | 60 DESCRIPTION | 8 R/00_classes.R | 5 R/01_show.R | 44 R/Module.R | 1 cleanup | 2 inst/NEWS | 23 inst/doc/Makefile | 74 inst/doc/Rcpp-FAQ.pdf |binary inst/doc/Rcpp-FAQ/Rcpp-FAQ.Rnw | 2 inst/doc/Rcpp-extending.pdf |binary inst/doc/Rcpp-introduction.Rnw | 1355 +++++++------ inst/doc/Rcpp-introduction.pdf |binary inst/doc/Rcpp-modules.pdf |binary inst/doc/Rcpp-package.pdf |binary inst/doc/Rcpp-quickref.pdf |binary inst/doc/Rcpp-sugar.pdf |binary inst/doc/Rcpp-unitTests.pdf |binary inst/doc/Rcpp.bib | 99 inst/doc/jss.bst |only inst/doc/unitTests-results/Rcpp-unitTests.html | 18 inst/doc/unitTests-results/Rcpp-unitTests.txt | 46 inst/include/Rcpp/Module.h | 40 inst/include/Rcpp/Vector.h | 6 inst/include/Rcpp/config.h | 2 inst/include/Rcpp/grow.h | 91 inst/include/Rcpp/module/Module_generated_ctor_signature.h | 18 inst/include/Rcpp/vector/RangeIndexer.h | 5 inst/include/RcppCommon.h | 6 inst/unitTests/runit.Module.R | 19 inst/unitTests/testRcppModule/src/stdVector.cpp | 7 src/exceptions.cpp | 2 32 files changed, 1167 insertions(+), 766 deletions(-)
As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page
Thanks to the help by Brian Ripley (who compiled QuantLib for 64 bit Windows), Josh Ulrich (who did the same for 32 bit Windows, and arranged the Windows builds) and Uwe Ligges (who runs win-builder for R) we once again have Windows binaries as well as the usual source distribution (and Debian binaries).
The only other change was minor fix to the documentation files. We had found that the pdf reference manual build would break for Uwe and
Kurt (using A4 paper settings) but not myself (using letter). Uwe finally tracked that down: we had some arguments to \url{}
with over seventy characters, and that broke typesetting. I commented those out (as the entries were in doxygen-generated QuantLib page
which have volatile names anyway) and fully automated builds now resume as usual. Thanks again to Uwe for that too. No other changes were made.
Thanks to CRANberries, there is also a diff to the previous release 0.3.6. Full changelog details, examples and more details about this package are at my RQuantLib page.
The short NEWS file extract follows below containing just Conrad's entry for 1.1.92. No further changes from our side.
And courtesy of CRANberries, here are the diffs to the previous release.0.2.18 2011-04-03 o Upgraded to Armadillo Version 1.1.92 "Jurassic Barbecue" * Bugfix in cor() * Automatic installation now requires CMake >= 2.6
ChangeLog | 8 ++ DESCRIPTION | 10 +-- inst/NEWS | 7 ++ inst/doc/Makefile | 2 inst/doc/RcppArmadillo-unitTests.tex |only inst/include/armadillo_bits/Cube_meat.hpp | 12 --- inst/include/armadillo_bits/Cube_proto.hpp | 4 - inst/include/armadillo_bits/Mat_meat.hpp | 2 inst/include/armadillo_bits/Mat_proto.hpp | 4 - inst/include/armadillo_bits/arma_version.hpp | 4 - inst/include/armadillo_bits/glue_cor_meat.hpp | 83 ++++++++++++-------------- 11 files changed, 73 insertions(+), 63 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
Given the lack of (more intense) training, I am also a lot slower: 21:50.7 was the chip time, or a 7:02 pace. We will see if I ever get faster again. On race day I am usually motivated; it remains to be seen if I get over to the track in the early morning to push myself through some speedwork.
Beginning users sometimes ask about how to use RInside inside larger projects. And as I had meant to experiment with embedding inside of the powerful Qt framework anyway, I started to dabble a little. A first result is now in the SVN sources of RInside.
My starting point was the classic tkdensity
demo that comes with
R itself. It is a good point of departure as Tcl/Tk makes it very
portable---in fact it should run on every platform that runs R---and quite
expressive. And having followed some of the GUI experiments around R over
the years, I have also seen various re-implementations using different GUI frameworks. And so I am adding
mine to this body of work:
The problem I addressed first was actual buildability. For the RInside examples, Romain and I provide a Makefile that just works by making calls to R itself to learn about flags for R, Rcpp and RInside such that all required headers and libraries are found. That is actually relatively straightforward (and documented in our vignettes) but a little intimidating at first---which is why a ready-made Makefile is a good thing.
Qt of course uses qmake
and the .pro
files to encode / resolve dependencies. So task one
was to map what our Makefile does into its variables. Turns out that wasn't all that
hard:
The double dollar signs and escaping of parentheses are a little tedious, but hey it works and expands the compiler and linker flags such that everything## -*- mode: Makefile; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- ## ## Qt usage example for RInside, inspired by the standard 'density ## sliders' example for other GUI toolkits ## ## Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois TEMPLATE = app HEADERS = qtdensity.h SOURCES = qtdensity.cpp main.cpp QT += svg ## comment this out if you need a different version of R, ## and set set R_HOME accordingly as an environment variable R_HOME = $$system(R RHOME) ## include headers and libraries for R RCPPFLAGS = $$system($$R_HOME/bin/R CMD config --cppflags) RLDFLAGS = $$system($$R_HOME/bin/R CMD config --ldflags) RBLAS = $$system($$R_HOME/bin/R CMD config BLAS_LIBS) RLAPACK = $$system($$R_HOME/bin/R CMD config LAPACK_LIBS) ## if you need to set an rpath to R itself, also uncomment #RRPATH = -Wl,-rpath,$$R_HOME/lib ## include headers and libraries for Rcpp interface classes RCPPINCL = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::CxxFlags\(\)\') RCPPLIBS = $$system($$R_HOME/bin/Rscript -e \'Rcpp:::LdFlags\(\)\') ## for some reason when building with Qt we get this each time ## so we turn unused parameter warnings off RCPPWARNING = -Wno-unused-parameter ## include headers and libraries for RInside embedding classes RINSIDEINCL = $$system($$R_HOME/bin/Rscript -e \'RInside:::CxxFlags\(\)\') RINSIDELIBS = $$system($$R_HOME/bin/Rscript -e \'RInside:::LdFlags\(\)\') ## compiler etc settings used in default make rules QMAKE_CXXFLAGS += $$RCPPWARNING $$RCPPFLAGS $$RCPPINCL $$RINSIDEINCL QMAKE_LFLAGS += $$RLDFLAGS $$RBLAS $$RLAPACK $$RCPPLIBS $$RINSIDELIBS ## addition clean targets QMAKE_CLEAN += qtdensity Makefile
The code itself is pretty straightforward too. We instantiate the
RInside object
as well as the main Qt application
object. We then instantiate a new object of class QtDensity
that
will launch the main widget; it is given a reference to the
RInside object.
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include <QApplication> #include "qtdensity.h" int main(int argc, char *argv[]) { RInside R(argc, argv); // create an embedded R instance QApplication app(argc, argv); QtDensity qtdensity(R); return app.exec(); }
The definition of the main object is pretty simple: a few private variables, and a few functions to interact with the GUI and get values from the radio buttons, slider or input field---as well as functions to update the chart or re-draw the random variables.
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #ifndef QTDENSITY_H #define QTDENSITY_H #include <RInside.h> #include <QMainWindow> #include <QHBoxLayout> #include <QSlider> #include <QSpinBox> #include <QLabel> #include <QTemporaryFile> #include <QSvgWidget> class QtDensity : public QMainWindow { Q_OBJECT public: QtDensity(RInside & R); private slots: void getBandwidth(int bw); void getKernel(int kernel); void getRandomDataCmd(QString txt); void runRandomDataCmd(void); private: void setupDisplay(void); // standard GUI boilderplate of arranging things void plot(void); // run a density plot in R and update the void filterFile(void); // modify the richer SVG produced by R QSvgWidget *m_svg; // the SVG device RInside & m_R; // reference to the R instance passed to constructor QString m_tempfile; // name of file used by R for plots QString m_svgfile; // another temp file, this time from Qt int m_bw, m_kernel; // parameters used to estimate the density QString m_cmd; // random draw command string }; #endif
Lastly, no big magic in the code either (apart from the standard magic provided
by RInside). A bit of standard GUI layouting, and
then some functions to pick values from the inputs as well as to compute /
update the output. One issue is worth mentioning. The screenshot and code
show the second version of this little application. I built a first one using
a standard portable network graphics (png) file. That was fine, but not
crisp as png is a pixel format so I went back and
experimented with scalable vector graphics (svg) instead. One can create svg output with
R in a number of ways, one of
which is the
cairoDevice
package by Michael Lawrence (who also wrote
RGtk2 and good
chunks of Ggobi). Now, it turns out that
Qt displays the so-called SVG
tiny standard whereas
R creates a fuller SVG format. Some
discussion with Michael reveals that one can modify the svg file suitably (which
is what the function filterFile
below does) and it all works. Well:
almost. There is a bug (and Michael thinks it is the SVG rendering) in which
the density estimate does not get clipped to the plotting region.
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8; -*- // // Qt usage example for RInside, inspired by the standard 'density // sliders' example for other GUI toolkits -- this time with SVG // // Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois #include <QtGui> #include "qtdensity.h" QtDensity::QtDensity(RInside & R) : m_R(R) { m_bw = 100; // initial bandwidth, will be scaled by 100 so 1.0 m_kernel = 0; // initial kernel: gaussian m_cmd = "c(rnorm(100,0,1), rnorm(50,5,1))"; // simple mixture m_R["bw"] = m_bw; // pass bandwidth to R, and have R compute a temp.file name m_tempfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("tfile <- tempfile()"))); m_svgfile = QString::fromStdString(Rcpp::as<std::string>(m_R.parseEval("sfile <- tempfile()"))); m_R.parseEvalQ("library(cairoDevice)"); setupDisplay(); } void QtDensity::setupDisplay(void) { QWidget *window = new QWidget; window->setWindowTitle("Qt and RInside demo: density estimation"); QSpinBox *spinBox = new QSpinBox; QSlider *slider = new QSlider(Qt::Horizontal); spinBox->setRange(5, 200); slider->setRange(5, 200); QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); spinBox->setValue(m_bw); QObject::connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(getBandwidth(int))); QLabel *cmdLabel = new QLabel("R command for random data creation"); QLineEdit *cmdEntry = new QLineEdit(m_cmd); QObject::connect(cmdEntry, SIGNAL(textEdited(QString)), this, SLOT(getRandomDataCmd(QString))); QObject::connect(cmdEntry, SIGNAL(editingFinished()), this, SLOT(runRandomDataCmd())); QGroupBox *kernelRadioBox = new QGroupBox("Density Estimation kernel"); QRadioButton *radio1 = new QRadioButton("&Gaussian"); QRadioButton *radio2 = new QRadioButton("&Epanechnikov"); QRadioButton *radio3 = new QRadioButton("&Rectangular"); QRadioButton *radio4 = new QRadioButton("&Triangular"); QRadioButton *radio5 = new QRadioButton("&Cosine"); radio1->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(radio1); vbox->addWidget(radio2); vbox->addWidget(radio3); vbox->addWidget(radio4); vbox->addWidget(radio5); kernelRadioBox->setMinimumSize(260,140); kernelRadioBox->setMaximumSize(260,140); kernelRadioBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); kernelRadioBox->setLayout(vbox); QButtonGroup *kernelGroup = new QButtonGroup; kernelGroup->addButton(radio1, 0); kernelGroup->addButton(radio2, 1); kernelGroup->addButton(radio3, 2); kernelGroup->addButton(radio4, 3); kernelGroup->addButton(radio5, 4); QObject::connect(kernelGroup, SIGNAL(buttonClicked(int)), this, SLOT(getKernel(int))); m_svg = new QSvgWidget(); runRandomDataCmd(); // also calls plot() QGroupBox *estimationBox = new QGroupBox("Density estimation bandwidth (scaled by 100)"); QHBoxLayout *spinners = new QHBoxLayout; spinners->addWidget(spinBox); spinners->addWidget(slider); QVBoxLayout *topright = new QVBoxLayout; topright->addLayout(spinners); topright->addWidget(cmdLabel); topright->addWidget(cmdEntry); estimationBox->setMinimumSize(360,140); estimationBox->setMaximumSize(360,140); estimationBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); estimationBox->setLayout(topright); QHBoxLayout *upperlayout = new QHBoxLayout; upperlayout->addWidget(kernelRadioBox); upperlayout->addWidget(estimationBox); QHBoxLayout *svglayout = new QHBoxLayout; svglayout->addWidget(m_svg); QVBoxLayout *outer = new QVBoxLayout; outer->addLayout(upperlayout); outer->addLayout(svglayout); window->setLayout(outer); window->show(); } void QtDensity::plot(void) { const char *kernelstrings[] = { "gaussian", "epanechnikov", "rectangular", "triangular", "cosine" }; m_R["bw"] = m_bw; m_R["kernel"] = kernelstrings[m_kernel]; // that passes the string to R std::string cmd1 = "Cairo(width=6,height=6,pointsize=10,surface='svg',filename=tfile); " "plot(density(y, bw=bw/100, kernel=kernel), xlim=range(y)+c(-2,2), main=\"Kernel: "; std::string cmd2 = "\"); points(y, rep(0, length(y)), pch=16, col=rgb(0,0,0,1/4)); dev.off()"; std::string cmd = cmd1 + kernelstrings[m_kernel] + cmd2; // stick the selected kernel in the middle m_R.parseEvalQ(cmd); filterFile(); // we need to simplify the svg file for display by Qt m_svg->load(m_svgfile); } void QtDensity::getBandwidth(int bw) { if (bw != m_bw) { m_bw = bw; plot(); } } void QtDensity::getKernel(int kernel) { if (kernel != m_kernel) { m_kernel = kernel; plot(); } } void QtDensity::getRandomDataCmd(QString txt) { m_cmd = txt; } void QtDensity::runRandomDataCmd(void) { std::string cmd = "y <- " + m_cmd.toStdString(); m_R.parseEvalQ(cmd); plot(); // after each random draw, update plot with estimate } void QtDensity::filterFile() { // cairoDevice creates richer SVG than Qt can display // but per Michaele Lawrence, a simple trick is to s/symbol/g/ which we do here QFile infile(m_tempfile); infile.open(QFile::ReadOnly); QFile outfile(m_svgfile); outfile.open(QFile::WriteOnly | QFile::Truncate); QTextStream in(&infile); QTextStream out(&outfile); QRegExp rx1("<symbol"); QRegExp rx2("</symbol"); while (!in.atEnd()) { QString line = in.readLine(); line.replace(rx1, "<g"); // so '<symbol' becomes '<g ...' line.replace(rx2, "</g");// and '</symbol becomes '</g' out << line << "\n"; } infile.close(); outfile.close(); }
What the little application does is actually somewhat neat for the few lines. One key features is that the generated data can be specified directly by an R expression which allows for mixtures (as shown, and as is the default). With that it easy to see how many points are needed in the second hump to make the estimate multi-modal, and how much of a distance between both centers is needed and so on. Obviously, the effect of the chosen kernel and bandwidth can also be visualized. And with the chart the being a support vector graphics display, we can resize and scale at will and it still looks crisp.
The code (for both the simpler png variant and the svg version shown here) is in the SVN repository for RInside and will be in the next release. Special thanks to Michael Lawrence for patiently working through some svg woes with me over a few emails.
Update: Some typos fixed.
Update 2: Two URLs corrected.
The short NEWS file extract follows below containing just Conrad's entry for 1.1.90. No further changes from our side.
And courtesy of CRANberries, here are the diffs to the previous release.0.2.17 2011-03-22 o Upgraded to Armadillo Version 1.1.90 "Inside Job" * Added .min() & .max(), which can provide the extremum's location * More robust mean(), var(), stddev()
ChangeLog | 6 DESCRIPTION | 8 inst/NEWS | 7 inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 6 inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 36 +- inst/include/armadillo_bits/Cube_meat.hpp | 112 ++++++++- inst/include/armadillo_bits/Cube_proto.hpp | 14 - inst/include/armadillo_bits/Mat_meat.hpp | 98 +++++++ inst/include/armadillo_bits/Mat_proto.hpp | 10 inst/include/armadillo_bits/arma_version.hpp | 4 inst/include/armadillo_bits/fn_prod.hpp | 12 inst/include/armadillo_bits/fn_stddev.hpp | 18 - inst/include/armadillo_bits/fn_var.hpp | 18 - inst/include/armadillo_bits/glue_mixed_meat.hpp | 22 - inst/include/armadillo_bits/op_max_meat.hpp | 199 ++++++++++------ inst/include/armadillo_bits/op_max_proto.hpp | 21 + inst/include/armadillo_bits/op_mean_meat.hpp | 154 +++++++++++- inst/include/armadillo_bits/op_mean_proto.hpp | 22 + inst/include/armadillo_bits/op_min_meat.hpp | 199 ++++++++++------ inst/include/armadillo_bits/op_min_proto.hpp | 19 + inst/include/armadillo_bits/op_stddev_meat.hpp | 44 ++- inst/include/armadillo_bits/op_stddev_proto.hpp | 9 inst/include/armadillo_bits/op_var_meat.hpp | 198 +++++++++++---- inst/include/armadillo_bits/op_var_proto.hpp | 14 - 25 files changed, 925 insertions(+), 325 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
Weather was pretty bad: A forecast of rain materialized with a shower at the start, another at about the halfway mark and a more solid downpour at the end, while temperature where in the lower 40s. And as I train less than I used to, I was also few just a few second slower than last year at 1:39:55 (hand-stopped) but managed to sneak in just under 100 minutes (and having taken six seconds to the starting lime, the official non-chip time has me just over that mark). All-in-all another nice half-marathon and I was appropriately sore yesterday.
The short NEWS file extract follows below containing just Conrad's entry for 1.1.8.
And courtesy of CRANberries, here are the diffs to.2.15.0.2.16 2011-03-10 o Upgraded to Armadillo Version 1.1.8 "Kangaroo Steak" * Added floor() and ceil() * Added "not a number": math::nan() * Added infinity: math::inf() * Added standalone is_finite() * Faster min(), max(), mean() * Bugfix for a corner case with NaNs in min() and max()
ChangeLog | 6 DESCRIPTION | 10 inst/NEWS | 11 inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 6 inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 38 - inst/include/armadillo | 2 inst/include/armadillo_bits/Cube_meat.hpp | 10 inst/include/armadillo_bits/Mat_meat.hpp | 30 - inst/include/armadillo_bits/arma_ostream_meat.hpp | 119 ++--- inst/include/armadillo_bits/arma_ostream_proto.hpp | 8 inst/include/armadillo_bits/arma_version.hpp | 6 inst/include/armadillo_bits/arrayops_meat.hpp | 39 + inst/include/armadillo_bits/arrayops_proto.hpp | 5 inst/include/armadillo_bits/auxlib_meat.hpp | 10 inst/include/armadillo_bits/constants.hpp | 322 +++++++++++--- inst/include/armadillo_bits/diskio_meat.hpp | 46 +- inst/include/armadillo_bits/eglue_core_meat.hpp | 345 +++------------- inst/include/armadillo_bits/eop_aux.hpp | 16 inst/include/armadillo_bits/eop_core_meat.hpp | 105 +--- inst/include/armadillo_bits/eop_core_proto.hpp | 6 inst/include/armadillo_bits/fn_elem.hpp | 58 ++ inst/include/armadillo_bits/fn_misc.hpp | 53 ++ inst/include/armadillo_bits/fn_norm.hpp | 14 inst/include/armadillo_bits/format_wrap.hpp | 12 inst/include/armadillo_bits/op_max_meat.hpp | 43 - inst/include/armadillo_bits/op_mean_meat.hpp | 38 - inst/include/armadillo_bits/op_min_meat.hpp | 46 +- inst/include/armadillo_bits/op_var_meat.hpp | 27 - inst/include/armadillo_bits/restrictors.hpp | 9 inst/include/armadillo_bits/traits.hpp | 20 31 files changed, 782 insertions(+), 678 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The short NEWS file extract for both releases follows, also containing Conrad's entry for 1.1.6. A few minor tweaks were added but no user-visible changes:
And courtesy of CRANberries, here are the diffs to.2.140.2.15 2011-03-04 o Upgraded to Armadillo Version 1.1.6 “Baby Carpet Shark” * fixed size matrices and vectors can use auxiliary (external) memory * .in_range() can use span() arguments * subfields can use span() arguments 0.2.14 2011-03-02 o Support Run-Time Type Information (RTTI) on matrices by setting the state variable vec_state in Row and Col instantiation, with thanks to Conrad Sanderson for the hint o fastLm code simplified further by instantiating the Armadillo matrix and vector directly from the SEXP coming from R o inst/doc/Makefile now respects $R_HOME environment variable
ChangeLog | 14 - DESCRIPTION | 8 inst/NEWS | 10 inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 10 inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 39 +- inst/include/armadillo_bits/Col_meat.hpp | 51 +++ inst/include/armadillo_bits/Col_proto.hpp | 3 inst/include/armadillo_bits/Cube_meat.hpp | 52 +++ inst/include/armadillo_bits/Cube_proto.hpp | 7 inst/include/armadillo_bits/Mat_meat.hpp | 51 +++ inst/include/armadillo_bits/Mat_proto.hpp | 12 inst/include/armadillo_bits/Row_meat.hpp | 51 +++ inst/include/armadillo_bits/Row_proto.hpp | 3 inst/include/armadillo_bits/arma_version.hpp | 6 inst/include/armadillo_bits/config.hpp | 9 inst/include/armadillo_bits/field_meat.hpp | 220 ++++++++++++++-- inst/include/armadillo_bits/field_proto.hpp | 20 + inst/unitTests/runit.RcppArmadillo.R | 16 + 19 files changed, 521 insertions(+), 61 deletions(-)and to the previous release 0.2.13, respectivel
ChangeLog | 14 ++++++ DESCRIPTION | 6 +- inst/NEWS | 11 +++++ inst/doc/Makefile | 15 +++++-- inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 18 ++++---- inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 34 ++++++++-------- inst/include/RcppArmadillo/Col_meat.h | 24 ++++++----- inst/include/RcppArmadillo/Row_meat.h | 19 ++++---- src/fastLm.cpp | 15 ++----- 10 files changed, 94 insertions(+), 62 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
This version contains a build fix for the older 10.5.* version of OS X and its g++ 4.2.1 compiler; we now skip one test that upset it. CRAN builds for OS X should resume. We also added simple configuration support for the Intel Compiler; feedback would be welcome on the list. Lastly, documentation in the vignettes was expanded a little. The NEWS entry is below; more detail is in the ChangeLog file in the package and on the Rcpp Changelog page.
Thanks to CRANberries, there is also a diff to the previous release 0.9.1.0.9.2 2011-02-23 o The unitTest runit.Module.client.package.R is now skipped on older OS X releases as it triggers a bug with g++ 4.2.1 or older; OS X 10.6 is fine but as it no longer support ppc we try to accomodate 10.5 too Thanks to Simon Urbanek for pinning this down and Baptiste Auguie and Ken Williams for additonal testing o RcppCommon.h now recognises the Intel Compiler thanks to a short patch by Alexey Stukalov; this turns off Cxx0x and TR1 features too o Three more setup questions were added to the Rcpp-FAQ vignette o One question about RcppArmadillo was added to the Rcpp-FAQ vignette
As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page
There are only two changes to two files where an explicit conversion as per Rcpp::as<double> was called for. A Debian archive rebuild had triggered one of those fails to build from source bug reports as the compiler version seems to be more finicky now than when version 0.3.5 was uploaded in November. No other changes were made.
Thanks to CRANberries, there is also a diff to the previous release 0.3.5. Full changelog details, examples and more details about this package are at my RQuantLib page.
The short NEWS file extract follows, also containing Conrad's entry for 1.1.4:
And courtesy of CRANberries, here is the diff to the previous release 0.2.12:0.2.13 2011-02-18 o Upgraded to Armadillo Version 1.1.4 "Manta Lodge" * Faster sort() * Updated installation to detect recent versions of Intel's MKL * Added interpretation of arbitrary "flat" subcubes as matrices
Diff between RcppArmadillo versions 0.2.12 dated 2011-02-16 and 0.2.13 dated 2011-02-19 ChangeLog | 6 DESCRIPTION | 14 inst/NEWS | 8 inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 6 inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 36 inst/include/armadillo_bits/Col_meat.hpp | 64 + inst/include/armadillo_bits/Col_proto.hpp | 3 inst/include/armadillo_bits/Cube_meat.hpp | 124 ++ inst/include/armadillo_bits/Cube_proto.hpp | 7 inst/include/armadillo_bits/Mat_meat.hpp | 696 +++++++++++--- inst/include/armadillo_bits/Mat_proto.hpp | 36 inst/include/armadillo_bits/Row_meat.hpp | 62 + inst/include/armadillo_bits/Row_proto.hpp | 3 inst/include/armadillo_bits/arma_version.hpp | 4 inst/include/armadillo_bits/arrayops_meat.hpp | 76 - inst/include/armadillo_bits/debug.hpp | 254 ++++- inst/include/armadillo_bits/field_meat.hpp | 44 inst/include/armadillo_bits/field_proto.hpp | 2 inst/include/armadillo_bits/fn_accu.hpp | 15 inst/include/armadillo_bits/fn_prod.hpp | 10 inst/include/armadillo_bits/forward_proto.hpp | 8 inst/include/armadillo_bits/injector_meat.hpp | 70 + inst/include/armadillo_bits/injector_proto.hpp | 4 inst/include/armadillo_bits/op_sort_meat.hpp | 242 ++--- inst/include/armadillo_bits/op_sort_proto.hpp | 15 inst/include/armadillo_bits/span.hpp | 72 + inst/include/armadillo_bits/subview_cube_meat.hpp | 759 +++++++++++++--- inst/include/armadillo_bits/subview_cube_proto.hpp | 19 inst/include/armadillo_bits/subview_field_meat.hpp | 83 + inst/include/armadillo_bits/subview_field_proto.hpp | 11 inst/include/armadillo_bits/subview_meat.hpp | 118 +- inst/include/armadillo_bits/subview_proto.hpp | 21 33 files changed, 2113 insertions(+), 779 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
The short NEWS file extract follows, also containing Conrad's entry for 1.1.2:
And courtesy of CRANberries, here is the diff to the previous release 0.2.11:0.2.12 2011-02-15 o Upgraded to Armadillo Version 1.1.2 “Flood Kayak” * Faster prod() * Faster solve() for compound expressions * Fix for compilation using GCC's C++0x mode * Fix for matrix handling by subcubes
Diff between RcppArmadillo versions 0.2.11 dated 2011-01-08 and 0.2.12 dated 2011-02-16 RcppArmadillo-0.2.11/RcppArmadillo/inst/include/armadillo_bits/syslib_proto.hpp |only RcppArmadillo-0.2.12/RcppArmadillo/ChangeLog | 6 RcppArmadillo-0.2.12/RcppArmadillo/DESCRIPTION | 17 RcppArmadillo-0.2.12/RcppArmadillo/inst/NEWS | 12 RcppArmadillo-0.2.12/RcppArmadillo/inst/doc/RcppArmadillo-unitTests.pdf |binary RcppArmadillo-0.2.12/RcppArmadillo/inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 6 RcppArmadillo-0.2.12/RcppArmadillo/inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 30 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/README | 1 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo | 13 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Base.hpp | 15 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Col_meat.hpp | 14 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Col_proto.hpp | 8 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Cube_meat.hpp | 6 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Mat_meat.hpp | 20 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Mat_proto.hpp | 15 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Row_meat.hpp | 14 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/Row_proto.hpp | 8 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/arma_config.hpp | 10 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/arma_version.hpp | 8 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/arrayops_meat.hpp |only RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/arrayops_proto.hpp | 448 +--------- RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/auxlib_meat.hpp | 63 - RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/auxlib_proto.hpp | 10 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/compiler_setup.hpp | 8 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/config.hpp | 20 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/debug.hpp | 27 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/fn_conv_to.hpp | 60 - RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/fn_prod.hpp | 40 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/glue_solve_meat.hpp | 10 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/glue_solve_proto.hpp | 4 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/injector_meat.hpp | 6 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/op_dot_meat.hpp | 2 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/op_prod_meat.hpp | 29 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/op_reshape_meat.hpp | 8 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/op_trans_meat.hpp | 2 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/op_trimat_meat.hpp | 4 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/podarray_meat.hpp | 4 RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/subview_cube_meat.hpp | 50 - RcppArmadillo-0.2.12/RcppArmadillo/inst/include/armadillo_bits/subview_meat.hpp | 8 39 files changed, 339 insertions(+), 667 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
This version contains mostly bug-fixes and rather few enhancements. The changes are mostly 'internal fixes' and not user-facing; they mostly address some issues in memory management which, while not tripping up the unit tests or common usage, caused trouble for advanced Rcpp modules use and repeated memory allocation / deallocation. This bit Doug Bates repeatedly, and he put his head down and debugged the issue. A number of changes fairly deep-down in Rcpp (as well as in R-devel) later, this looks much better and we owe him a hearfelt Thank You!
A big Thanks! also goes to Luke Tierney who out some new memory debugging code into R-devel which the --enable-strict-barrier in R 2.13.0 (due in April) will enable. A related fix is also in R 2.12.2 due on the 25th. The NEWS entry is below; more detail is in the ChangeLog file in the package.
Thanks to CRANberries, there is also a diff to the previous release 0.9.0.0.9.1 2011-02-14 o A number of internal changes to the memory allocation / protection of temporary objects were made---with a heartfelt "Thank You!" to both Doug Bates for very persistent debugging of Rcpp modules code, and to Luke Tierney who added additional memory allocation debugging tools to R-devel (which will be in R 2.13.0 and may also be in R 2.12.2) o Removed another GNU Make-specific variable from src/Makevars in order to make the build more portable; this was noticed on FreeBSD o On *BSD, do not try to compute a stack trace but provide file and line number (which is the same behaviour as implemented in Windows) o Fixed an int conversion bug reported by Daniel Sabanes Bove on r-devel, added unit test as well o Added unit tests for complex-typed vectors (thanks to Christian Gunning) o Expanded the Rcpp-quickref vignette (with thanks to Christian Gunning) o Additional examples were added to the Rcpp-FAQ vignette
As always, even fuller details are on the Rcpp Changelog page and the Rcpp page which also leads to the downloads, the browseable doxygen docs and zip files of doxygen output for the standard formats. A local directory has source and documentation too. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page
All in all a great concert. Hard not to love when you twelve-man strong brass section featuring four trumpets, three trombones, five saxophones supported by a nice rhythm section of three. Recommended.
@CRANberriesFeed
to
receive theses messages.
For the technically minded, adding this to the existing 200-line program which runs all of CRANberries was very easy. CRANberries relies only on R itself and a few Unix tools like diffstat as well as the simple blosxom txt-to-html/rss 'blog compiler'. The tweeting itself is now done by this new function
which simply pipes the message in Greg KH's bti program (which is now a new dependency). Special thanks to its Debian maintainer Gregor Herrmann for some helpful emails; I am using the newest release 0.29 which itself needs liboauth0. Once OAuth tokens are set-up (and see here for how to do that) all we need is the three-liner above.tweetNewBlogEntry <- function(curPkg, curVer, reposurl) { ## tests reveal that pipe(), cat(), close() is easiest ## to send multiple messages, may need --background option con <- pipe("bti --config bti.conf", "w") cat("New CRAN package", curPkg, "with initial version", curVer, " http://goo.gl/pgljT\n", file=con) close(con) }
At this point I am not too sure what to do about updated packages. One message per updated package seems too noisy. To be seen---comments or suggestions welcome.
RcppBDT stands for Rcpp Boost Date_Time. It employs what we call Rcpp modules: a mechanism which provides easier ways to expose C++ functions and classes to R (and which bears some resemblance to Boost.Python---see this vignette about Rcpp modules for more details). And thus RcppBDT provides R users with access to (some) Boost Date.Time functionality.
I used Boost Date.Time because
it is widely known, useful and well tested. It can also be used in pure
template mode not requiring linking (if one foregoes string parsing and
formatting which is fine here as we get this from R already; it can be added
via a #define
in the header file). With that, the package
is rather portable as it only needs to find the Boost headers. (And no, I
have not yet added a configure option for that.)
Basic usage follows Rcpp modules and provides the C++ class via a Reference
Class in R. That means using a new
constructor and assessing functions via
the $
operator. Here is an example:
Not very exiting yet: we create a date, using explicit year, months and date arguments and then format it. Something more useful follows:R> library(RcppBDT) Creating a new generic function for "print" in "RcppBDT" Creating a new generic function for "format" in "RcppBDT" R> d <- new(bdtMod$date, 2011, 1, 18) R> format(d) [1] "2011-01-18" R>
We can use accessors to extracts parts of the date, or use functions to convert the date to different representations such as a modified Julian date. Moreover, given a date, we can apply helper functions such as get me the date of the beginning of the next month.R> d$getDayOfWeek() [1] 2 R> d$getModJulian() [1] 55579 R> d$getFirstOfNextMonth() [1] "2011-02-01" R>
More interesting still are helper functions such as the ones below. Note that this also shows the alternate access method using wrapper functions I added for the package, this may be more familiar to most R users:
This uses some of the constantsR> getNthDayOfWeek(third, Wed, Dec, 2010) [1] "2010-12-15" R> getLastDayOfWeekInMonth(Sat, Dec, 2010) [1] "2010-12-25" R> getFirstDayOfWeekInMonth(Sat, Dec, 2010) [1] "2010-12-04" R> getFirstDayOfWeekAfter(Wed, as.Date("2010-12-31")) [1] "2011-01-05" R>
Jan
, Feb
,
... , Dec
; Sun
, Mon
, ...,
Sat
and first
... fifth
defined in the package; normal integers can also be used. The third Wednesday in a month is also known as the IMM
Date to Finance-heads; the example was borrowed from Whit's
earlier rboostdatetime code on github.
More examples are in the demo available with the package and accessible via
demo(RcppBDT)
once you install the package.
As always, feedback would be welcome, both on the usefulness (or lack thereof) of the Boost Date.Time functionality as well as on the Rcpp modules wrapping. Additional Boost Date.Time functionality (durations, times, ...) may be added; contributions would be welcome. The rcpp-devel mailing list off the R-Forge page for Rcpp is the best place to start a discussion.
It is a fine article motivated by all the usual reasons that are e.g. mentioned in the Google Tech Talk which Romain and I gave last October about our work around Rcpp. But it is just not simple.
Allow me to explain. When Jeff showed this C language file
and then needs several paragraphs to explain what is going on, what is needed to compile and then how to load it --- I simply could not resist. Almost immediately, I emailed back to him something as simple as this using both our Rcpp package as well as the wonderful inline package by Oleg which Romain and I more or less adopted:#include <R.h> #include <Rinternals.h> SEXP esoteric_rev (SEXP x) { SEXP res; int i, r, P=0; PROTECT(res = allocVector(REALSXP, length(x))); P++; for(i=length(x), r=0; i>0; i--, r++) { REAL(res)[r] = REAL(x)[i-1]; } copyMostAttrib(x, res); UNPROTECT(P); return res; }
Here we load inline, and then define a three-line C++ program using facilities from our Rcpp package. All we need to revert a vector is to first access its R object in C++ by instantiating the R vector as alibrary(inline) ## for cxxfunction() src <- 'Rcpp::NumericVector x = Rcpp::NumericVector(xs); std::reverse(x.begin(), x.end()); return(x);' fun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp") fun( seq(0, 1, 0.1) )
NumericVector
.
These C++ classes then provide iterators which are compatible with the
Standard Template Library (STL). So we simply
call the STL function reverse
pointing the beginning and end
of the vector, and are done! Rcpp then allows us the return the C++ vector
which it turns into an R vector. Efficient in-place reversal, just like Jeff
had motivated, in three lines. Best of all, we can execute this from within R itself:
R> library(inline) ## for cxxfunction() R> src <- 'Rcpp::NumericVector x = Rcpp::NumericVector(xs); + std::reverse(x.begin(), x.end()); + return(x);' R> fun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp") R> fun( seq(0, 1, 0.1) ) [1] 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 R>
Lastly, Jeff shows a more complete example wherein a new vector is created,
and any potential attributes are copied as well. Naturally, we can do that
too. First, we used clone()
to make a deep copy (ie forcing
creation of a new object rather than a mere proxy) and use the same R API
function he accessed---but it our case both prefixed with ::Rf_
for R remapping (to protect clashed with other functions with identical names) and a global
namespace identifier (as it is a global C function from R).
Both theR> library(inline) R> src <- 'Rcpp::NumericVector x = Rcpp::clone<Rcpp::NumericVector>(xs); + std::reverse(x.begin(), x.end()); + ::Rf_copyMostAttrib(xs, x); + return(x);' R> fun <- cxxfunction(signature(xs="numeric"), body=src, plugin="Rcpp") R> obj <- structure(seq(0, 1, 0.1), obligatory="hello, world!") R> fun(obj) [1] 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 attr(,"obligatory") [1] "hello, world!" R> obj [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 attr(,"obligatory") [1] "hello, world!" R>
obj
variable and the new copy contain the desired data
attribute, the new copy is reversed, the original is untouched---and all in
four lines of C++ called via one
inline call. I have
now been going on for over one hundred lines yet I never had to mention
memory management, pointers, PROTECT
or other components of the
R API for C. Hopefully, this short writeup provided an idea of why
Romain and I think
Rcpp is the way to
go for creating C/C++ functions for extending and enhancing
R.
Classifying markets as overbought or oversold is a popular heuristic. It starts from computing a rolling smoothed estimate of the prices, usually via a (exponential or standard) moving average over a suitable number of days (where Bespoke uses 50 days, see here). This is typically coupled with a (simple) rolling standard deviation. Overbought and oversold regions are then constructed by taking the smoothed mean plus/minus one and two standard deviations.
Doing this is in R is pretty easy thanks to the combination of R's rich base functions and its add-on packages from CRAN. Below is a simply function I wrote a couple of months ago---and I figured I might as well release. It relies on the powerful packages quantmod and TTR by my pals Jeff Ryan and Josh Ulrich, respectively.
## plotOBOS -- displaying overbough/oversold as eg in Bespoke's plots ## ## Copyright (C) 2010 - 2011 Dirk Eddelbuettel ## ## This is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. suppressMessages(library(quantmod)) # for getSymbols(), brings in xts too suppressMessages(library(TTR)) # for various moving averages plotOBOS <- function(symbol, n=50, type=c("sma", "ema", "zlema"), years=1, blue=TRUE) { today <- Sys.Date() X <- getSymbols(symbol, src="yahoo", from=format(today-365*years-2*n), auto.assign=FALSE) x <- X[,6] # use Adjusted type <- match.arg(type) xd <- switch(type, # compute xd as the central location via selected MA smoother sma = SMA(x,n), ema = EMA(x,n), zlema = ZLEMA(x,n)) xv <- runSD(x, n) # compute xv as the rolling volatility strt <- paste(format(today-365*years), "::", sep="") x <- x[strt] # subset plotting range using xts' nice functionality xd <- xd[strt] xv <- xv[strt] xyd <- xy.coords(.index(xd),xd[,1]) # xy coordinates for direct plot commands xyv <- xy.coords(.index(xv),xv[,1]) n <- length(xyd$x) xx <- xyd$x[c(1,1:n,n:1)] # for polygon(): from first point to last and back if (blue) { blues5 <- c("#EFF3FF", "#BDD7E7", "#6BAED6", "#3182BD", "#08519C") # cf brewer.pal(5, "Blues") fairlylight <- rgb(189/255, 215/255, 231/255, alpha=0.625) # aka blues5[2] verylight <- rgb(239/255, 243/255, 255/255, alpha=0.625) # aka blues5[1] dark <- rgb(8/255, 81/255, 156/255, alpha=0.625) # aka blues5[5] } else { fairlylight <- rgb(204/255, 204/255, 204/255, alpha=0.5) # grays with alpha-blending at 50% verylight <- rgb(242/255, 242/255, 242/255, alpha=0.5) dark <- 'black' } plot(x, ylim=range(range(xd+2*xv, xd-2*xv, na.rm=TRUE)), main=symbol, col=fairlylight) # basic xts plot polygon(x=xx, y=c(xyd$y[1]+xyv$y[1], xyd$y+2*xyv$y, rev(xyd$y+xyv$y)), border=NA, col=fairlylight) # upper polygon(x=xx, y=c(xyd$y[1]-1*xyv$y[1], xyd$y+1*xyv$y, rev(xyd$y-1*xyv$y)), border=NA, col=verylight)# center polygon(x=xx, y=c(xyd$y[1]-xyv$y[1], xyd$y-2*xyv$y, rev(xyd$y-xyv$y)), border=NA, col=fairlylight) # lower lines(xd, lwd=2, col=fairlylight) # central smooted location lines(x, lwd=3, col=dark) # actual price, thicker invisible(NULL) }
After downloading data and computing the rolling smoothed mean and standard deviation, it really is just a matter of plotting (appropriate) filled polygons. Here I used colors from the neat RColorBrewer package with some alpha blending. Colors can be turned off via an option to the function; ranges, data length and type of smoother can also be picked.
To call this in R, simply source the file and the call, say, plotOBOS("^GSPC", years=2)
which creates a two-year plot of the SP500 as shown here:
This shows the market did indeed bounce off the oversold lows nicely on a few occassions in 2009 and 2010 --- but also continued to slide after hitting the condition. Nothing is foolproof, and certainly nothing as simple as this is, so buyer beware. But it may prove useful in conjunction with other tools.
The code for the script is here and of course available under GPL 2 or later. I'd be happy to help incorporate it into some other finance package. Lastly, if you read this post this far, also consider our R / Finance conference coming at the end of April.
Edit: Corrected several typos with thanks to Josh.
Given Allen Toussaint's live-long association with New Orleans, there was a lot of music inspired by the town, including a modern rendition of an old Sidney Bechet tune as well as other material came from his most recent album The Bright Mississippi. And, given Allen Toussaint's fame in Rhythm and Blues circles, there was lot of R&B too. I found the program to be a little uneven and unbalanced that way---but it was still a great show, and he surely brought the house down. He is a charming old school performer, and maybe the audience warmed his heart right before the concert started with a quick Happy Birthday rendition as yesterday was in fact his this 73rd birthday! Don Byron and Nicholas Payton were, as expected, stellar in their own right. A nice night out.
The NEWS file entry follows below:
And courtesy of CRANberries, here is the diff to the previous release 0.2.1:0.2.2 2011-01-11 o Applied two patches by Murray Stokely which - correct a typo preventing some functions from being called, - add bounds checking in call to google protobuf library, - add a new name method - add a tiny unit test for the above - add more graceful error handling - add support for import patterns other than .proto$, - add simple reading file that does not exist (exception) test - add simple repeated field unit test
ChangeLog | 35 DESCRIPTION | 8 R/00classes.R | 11 R/internals.R | 7 R/wrapper_EnumDescriptor.R | 6 inst/NEWS | 12 inst/THANKS |only inst/doc/Makefile | 4 inst/doc/RProtoBuf-quickref.pdf |binary inst/doc/RProtoBuf-unitTests.pdf |binary inst/doc/RProtoBuf.pdf | 2362 +++++++++----------- inst/doc/unitTests-results/RProtoBuf-unitTests.html | 20 inst/doc/unitTests-results/RProtoBuf-unitTests.txt | 23 inst/unitTests/runit.addressbook.R | 11 inst/unitTests/runit.enums.R |only inst/unitTests/runit.golden.message.R | 7 inst/unitTests/runit.import.R |only man/EnumDescriptor-class.Rd | 42 man/EnumValueDescriptor-class.Rd | 23 man/readProtoFiles.Rd | 3 src/DescriptorPoolLookup.cpp | 26 src/S4_classes.h | 6 src/wrapper_EnumDescriptor.cpp | 25 src/wrapper_EnumValueDescriptor.cpp | 25 24 files changed, 1357 insertions(+), 1299 deletions(-)
As always, there is more information at the RProtoBuf page which has a draft package vignette, a 'quick' overview vignette and a unit test summary vignette. Questions, comments etc should go to the rprotobuf mailing list off the RProtoBuf page at R-Forge.
The only other change is the addition of an unexported function
SHLIB
which can be used to compiled a single source file into a
loadable shared library file for R, while automagically find Rcpp and
RcppArmadillo headers and the Rcpp library.
The short NEWS file extract follows, also containing Conrad's entry for 1.1.0:
0.2.11 2011-01-06 o Upgraded to Armadillo Version 1.1.0 “Climate Vandal” * Extended submatrix views, including access to elements whose indices are specified in a separate vector * Added handling of raw binary files by save/load functions * Added cumsum() * Added interpretation of matrices as triangular via trimatu()/trimatl() * Faster solve(), inv() via explicit handling of triangular matrices * The stream for logging of errors and warnings can now be changed o New unexported R function SHLIB, a small wrapper around R CMD SHLIB, which can be used as Rscript -e "RcppArmadillo:::SHLIB('foo.cpp')"And courtesy of CRANberries, here is the diff to the previous release 0.2.10:
ChangeLog | 17 DESCRIPTION | 12 R/SHLIB.R |only inst/NEWS | 13 inst/doc/Makefile | 5 inst/doc/RcppArmadillo-unitTests.pdf |binary inst/doc/unitTests-results/RcppArmadillo-unitTests.html | 16 inst/doc/unitTests-results/RcppArmadillo-unitTests.txt | 34 inst/include/armadillo | 9 inst/include/armadillo_bits/Col_meat.hpp | 25 inst/include/armadillo_bits/Col_proto.hpp | 5 inst/include/armadillo_bits/Cube_meat.hpp | 54 + inst/include/armadillo_bits/Cube_proto.hpp | 7 inst/include/armadillo_bits/Mat_meat.hpp | 469 ++++++++++++ inst/include/armadillo_bits/Mat_proto.hpp | 54 + inst/include/armadillo_bits/Proxy.hpp | 63 + inst/include/armadillo_bits/Row_meat.hpp | 25 inst/include/armadillo_bits/Row_proto.hpp | 3 inst/include/armadillo_bits/arma_version.hpp | 11 inst/include/armadillo_bits/auxlib_meat.hpp | 102 ++ inst/include/armadillo_bits/auxlib_proto.hpp | 13 inst/include/armadillo_bits/debug.hpp | 101 +- inst/include/armadillo_bits/diskio_meat.hpp | 280 +++++++ inst/include/armadillo_bits/diskio_proto.hpp | 9 inst/include/armadillo_bits/field_meat.hpp | 23 inst/include/armadillo_bits/field_proto.hpp | 3 inst/include/armadillo_bits/fn_cumsum.hpp |only inst/include/armadillo_bits/fn_dot.hpp | 66 + inst/include/armadillo_bits/fn_elem.hpp |only inst/include/armadillo_bits/fn_inv.hpp | 27 inst/include/armadillo_bits/fn_max.hpp | 17 inst/include/armadillo_bits/fn_mean.hpp | 17 inst/include/armadillo_bits/fn_median.hpp | 15 inst/include/armadillo_bits/fn_min.hpp | 21 inst/include/armadillo_bits/fn_misc.hpp | 604 ---------------- inst/include/armadillo_bits/fn_prod.hpp | 15 inst/include/armadillo_bits/fn_solve.hpp | 22 inst/include/armadillo_bits/fn_stddev.hpp | 15 inst/include/armadillo_bits/fn_sum.hpp | 25 inst/include/armadillo_bits/fn_trimat.hpp |only inst/include/armadillo_bits/fn_var.hpp | 15 inst/include/armadillo_bits/forward_proto.hpp | 7 inst/include/armadillo_bits/glue_solve_meat.hpp | 32 inst/include/armadillo_bits/glue_solve_proto.hpp | 12 inst/include/armadillo_bits/lapack_proto.hpp | 103 ++ inst/include/armadillo_bits/op_cumsum_meat.hpp |only inst/include/armadillo_bits/op_cumsum_proto.hpp |only inst/include/armadillo_bits/op_dot_meat.hpp | 46 + inst/include/armadillo_bits/op_dot_proto.hpp | 9 inst/include/armadillo_bits/op_find_meat.hpp | 59 - inst/include/armadillo_bits/op_inv_meat.hpp | 13 inst/include/armadillo_bits/op_inv_proto.hpp | 14 inst/include/armadillo_bits/op_trimat_meat.hpp |only inst/include/armadillo_bits/op_trimat_proto.hpp |only inst/include/armadillo_bits/podarray_meat.hpp | 7 inst/include/armadillo_bits/span.hpp | 9 inst/include/armadillo_bits/subview_elem1_meat.hpp |only inst/include/armadillo_bits/subview_elem1_proto.hpp |only inst/include/armadillo_bits/subview_meat.hpp | 321 ++++++-- inst/include/armadillo_bits/subview_proto.hpp | 1 inst/include/armadillo_bits/typedef.hpp | 4 inst/include/armadillo_bits/unwrap.hpp | 135 +++ 62 files changed, 2155 insertions(+), 829 deletions(-)
More information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the R-Forge page.
After a short reflection, I decided to keep it simple. I undusted a wishlist I had once created over at Amazon, yet never publicised. And amazingly, within minutes of minutes of passing the URL on, I received a cheerful email stating that three books are their merry way. Appropriately enough, two were from Springer's useR! series and another one was a brand new GPU programming title. And they all arrived yesterday. I am still stunned.
So with that, my time to say thanks! This was a genuinely nice gesture, and I really appreciate it. I have been doing open source work for over fifteen years now, and I would not still be doing it if I did not enjoy it myself. I continue to learn a lot in the process, and have had a chance to meet lot interesting folks. Yet it is also nice to get a little Thanks every now and then.