The One where I spent a morning because -0.5 turned to be parsed as 1/2

This summer, I have been doing some amazing stuff for GeoGebra. First of all, I would like to thank two people: Miguel, my mentor, who guided me through all that really advanced mathematical stuff; and Heinz Kredel, JAS creator and developer, who answered all my questions and implemented my suggestions as quickly as I could write them.

This story is about a problem we found in JAS. It was really subtle, so I may need a brief introduction to the project I worked on: LocusEqu. That project retrieves the equation of “any” geometrical locus. If you don’t know what a locus is, Wolfram Math World defines it as “the set of all points (usually forming a curve or surface) satisfying some condition” . LocusEqu generates a few EquationExpression, and then, by using a EquationTranslator, it generates a GenPolynomial<BigRational> object.

For translating doubles, it calls the BigRational constructor whose only argument is a String. This is the code:

Can you spot the bug? Look at the 21st line. If s is “-0.5”, then n is new BigInteger(“-0”), and that’s what makes “-0.5” be parsed as 1/2.

Status update for GeoGebra.

My contributions for the first part of the first part of GSoC 2010 can be divided in two: general improvements and coding.

General improvements

I made a few general improvements on GeoGebra:

  1. Refactored build.dir in ant build file. Previously, build.dir wasn’t in the root directory.
  2. A few ant tasks were added, such compile-grammar, compile-oe (outside Eclipse), run-easyb and run-easyb-outside-eclipse.
  3. SVN properties were set in order to work outside Eclipse. This way, .class files will be kept out of the repo without the intervention of any Eclipse plugin.
  4. Easyb, a BDD groovy-based framework, has been included in order to test GeoGebra. It is not RSpec, but I guess it’ll do.

Coding

First, I started creating a few EquationPoint classes,  currently there are six EquationPoint children classes:

EquationPoint type hierarchy

  • EquationFreePoint represents an independent point.
  • EquationSymbolicPoint represents a dependent point,  EquationSpecialSymbolicPoint standing only for the locus point.
  • EquationNormalPoint and EquationPointVectorPoint are only auxiliar elements.

Then, a few EquationElement classes were added, these stand for the different constructions:

EquationElement type hierarchy

EquationElement is an abstract class containing a few basic methods:

  • forPoint: Given an EquationPoint, returns a String with the equation that means that the point is in the construction.
  • isAlgebraic: returns true if the construction is algebraic, and false otherwise.

Both EquationGenericCircle and EquationGenericLine are abstractions of specific line and circle contructions, all of them algebraic. EquationGenericSegment is to segment what EquationGenericLine is to lines. Obviously, EquationGenericSegment is not algebraic.

All of these classes are used together by EquationScope.

A pause for a screenshot.

Screeenshot

Click for enlarge.

A glimpse into the future.

What to do next?:

  • Maybe Equation should be a proper class, not just a String.
  • More equations.
  • Working out the locus equation.
  • Not using an algorithm twice.

Writing your own JRuby extension. First problem.

Denial
Maybe, when requiring your just created extension, you get a LoadError. If it is the first time you require it, it is quite likely that you have not followed JRuby requiring conventions. If you want to know how require works, you can find the best documentation ever about it in the comment before org.jruby.runtime.load.LoadService class.

Creative Commons License photo credit: cesarastudillo

Writing your own JRuby extension. Part I: BasicLibraryService.

Note: not code in this post, but you can see the code in Github. Follow the links!

Writing a JRuby extension is very easy, but there are almost not post out there about it. As far as I know, there is only one, Ola’s. It is a really good tutorial indeed, but it lacks some details that might be not-that-easy to solve. Please, take some time to read it and, if some details are different, do follow Ola’s way.

Everything’s ready now, so let’s start talking about BasicLibraryService. If you take a look at Nokogiri4J sourcecode, in ext/java/nokogiri folder, you will see a NokogiriService.java file. NokogiriService implements BasicLibraryService. This interface consists only of the method basicLoad which receives a Ruby object.

We will use this method to define classes and methods in the Ruby world. For defining a module, defineModule method is used with the name of the module. After that, modules and classes under that module can be defined easily by using the methods defineModuleUnder, which takes the name as parameter, and defineClassUnder, which takes the name and few parameters more. Let’s dive into it.

defineClassUnder needs three arguments. The first one is the class’ name. The second, is the parent class. If you have defined it previously, just passed it,  otherwise use RubyObject by calling the method getObject on the Ruby instance. The third parameter is an ObjectAllocator. ObjectAllocators returns intances of the classes in Java world. When instantiating Nokogiri::XML::Comment in Ruby world, JRuby will ask the ObjectAllocator for an instance of the Java class. It passes a Ruby object and the RubyClass being instantiated to the allocate method in the ObjectAllocator (more on RubyClass in following posts).

Finally, we will need to define some methods. Easiest way is by using the defineAnnotatedMethods. It takes a Java class as parameter. For knowing what this method does, you need to know a bit more about @JRubyMethod annotation (more on it in following post, have you realized the “Part I” in the title?). As you define methods, you may need to undefine some in a subclass. So easy! Use the undefineMethod method, which takes the name of the method as parameter (surprisingly, it undefines a method by redefining it!).

Next time, Implementing your first class.

Helping Nokogiri. Take II

PIZZA PRO 3000
Nokogiri and Pizza, what else can you ask for?

Ok. My fault. Now, let’s go get some work done.

First, if you haven’t done it, read the previous post about helping nokogiri and forgot about the script and memory leak. It seems that there are more important issues, so let’s fix them first. First run jruby test/test_jruby.rb from Nokogiri root. You’ll see a lot of errors (27 by now) and failures (14). Choose one, and get it green. After that, send me a pull request.

Ok. That sounds simple, but what if  the number of errors or failures raises? The rule I use is simple: keep the sum of both numbers going down and having a failure is better than having an error.

On the other hand, if you take a look at test/test_jruby.rb, you’ll see that not every test is in there. There is a reason for that. Even keeping the number of test low, you get a lot of errors/failures. If that annoys me with just 50 failures, imagine if I had a couple of hundreds errors. When all is right, I’ll add some more to keep the fun on.

Photo by Paul Johnston.

Do you wanna help us with pure-Java Nokogiri?

First things first, if you wanna help, you’ll need to clone the git repo. Just:

git clone git://github.com/tenderlove/nokogiri.git
cd nokogiri
git checkout --track -b java origin/java

Install the dependencies. Just:

rake install:deps

Because it uses some native libraries, you’ll need to do that with MRI. Finally, you’ll need to generate some files, just run jruby -S rake java:spec. For having a hprof file, you’ll need to run this script with the following command:

jr -J-Xmx32m -J-XX:+HeapDumpOnOutOfMemoryError nokogiri_doc_frag.rb

-J-Xmx32m limits the heap space to 32 Mb, and the other options makes the JVM to write a hprof file when a OutOfMemoryError is thrown. After that, you can inspect that file with the profiler you can find in NetBeans.

In next post, I’ll comment where I think the problem is.

Final Status Update (or How to get Nokogiri in JRuby without FFI)

Hi, all,

sorry for the silence all these months, but I’ve been working hard on Nokogiri. First things first, it is not complete yet. Anyway, I’m gonna tell you how to build a gem and start working with it.

Wooden vice - sharpening saw
Creative Commons License photo credit: Matthew Byrne

Clone the repo and checkout the java branch.

git clone git://github.com/tenderlove/nokogiri.git
git checkout --track -b java origin/java

Next step: build the gem. As easy as jruby -S rake java:gem. Maybe, you need to install rexical and racc. jruby -S rake install:deps would do.

Finally, you have a gem in the pkg folder. Install it, and you’re done.

Updated: Take a look here if you wanna help.

Status Update: RMagick4J, Nokogiri, ruby2java and a possible MagickWand4J

It’s been long time since last status update, but there are some things to tell, so here I am.

Thankfully, this year I’m a GSoC student again (and my mentor is Tom too). The main part of my project would be porting Nokogiri to JRuby, so I haven’t code for RMagick for a while now.

Let’s start with the status update then.

Nokogiri

I’ve been working on Nokogiri for a while. I forked Charles’ repo in Github, and I’ve implemented some cool features. For example, today I got my XML::Reader implementation to pass all tests in test_reader.rb. I hope I’ll be able to make a release this month (cross your fingers).

On the other hand, I got my first patch accepted in Nokogiri’s main repo.

RMagick4J

Not to much work done here, sorry. I haven’t code anything for a while now. Migrating from mercurial to git is already planned, but before that I would like to do a few commits more. Anyway, I’m quite happy with this project. Some people are using it and reporting bugs (in the end, those little things are all that matters). What else can I ask for?

Please, if you find a bug, report it here.

MagickWand

Tim Hunter (creator of RMagick) released MagickWand recently. I’ve been considering porting it to JRuby too. I have to take a deeper look at the C code, but, by now, I think it could be a good way to lead RMagick4J development. If finally I port it, I will split RMagick4J in two projects (Magick4J and RMagick4J). This way, MagickWand4J and RMagick4J would share the same java codebase, as MagickWand and RMagick share ImageMagick.

ruby2java

Take a look here. Awesome, isn’t it? And as soon as I have some time to work on it, siesta will be out too…

P.D. By the way, no more personal stuff in this blog. That stuff is now here, and only in Spanish (sorry about that).

RMagick4J 0.3.7 Happy Birthmonth released.

RMagick4J 0.3.7 Happy Birthmonth has been released!

RMagick is a Ruby binding to ImageMagick and GraphicsMagick. RMagick4J implements ImageMagick functionality and the C portions of RMagick for use with JRuby.

Current stable version: 0.3.7
Project URL: http://kenai.com/projects/rmagick4j
Installation: gem install rmagick4j

New effects:

  • Charcoal
  • Edge
  • Implode
  • Negate
  • Normalize
  • Shade
  • Solarize
  • Wave

(I think that’s all that you need to use simple_captcha)

Major bugs resolved:

  • blur_image produced different images from RMagick.
  • Draw#push and Draw#pop didn’t work correctly in some cases.

Furthermore, RMagick4J does not depend on jhlabs library anymore (the gem has lost some weight!).

Thanks to:

  • Tim Hunter and the ImageMagick team (obviously).
  • JRuby community for its support.
  • Everyone that has reported a bug, ask for help in the #jruby channel or suggest a new library compatibility.

Please try out your applications with rmagick4j and help us provide feedback (even birthmonth cake!). It is our goal to make a fully-compatible implementation of RMagick4j in JRuby.

You have some image examples here: http://www.serabe.com/rmagick4j

This is a very special release, cause March is my birthmonth.

Happy Birthmonth to:

  • SuperTaz
  • everyone else whose birthmonth is march
  • and me!

New RMagick4J release.

RMagick aims to implement the ImageMagick funcionality and the C portions of RMagick for make it works in JRuby.

Current stable version: 0.3.5
Project URL: http://code.google.com/p/rmagick4j/
Installation: gem install rmagick4j

Google Summer of Code project should be thanked for making this new release possible.

In release 0.3.5 the following improvements have been made:

  • Implemented Draw primitives (affice, arc, pattern, path).
  • Improved Image and ImageList:
  • Implemented more of Pixel (from_HSL, to_HSL, <=>, fcmp, intensity).
  • Implemented the fill classes.
  • Added a side-by-side (MRI vs JRuby) image testing tool named Bullseye.
  • Added 680 color names. It can search, but not retrieve the name correctly capitalized.
  • Changed gem name from RMagick4J to rmagick4j.

This version should allow Gruff Graphs and Ruports to largely work without issues. Please try out your applications with rmagick4j and help us provide feedback. It is our goal to make a fully-compatible implementation of RMagick4j in JRuby.