Since your package came up in several discussions so far and most notably in this highly discussed post on StackExchange, I'd like to leave some words. There are two things I appreciate in your package and your work in general
- You seem to be one of the few experts on integration that does his work in the open and not behind closed doors. This is especially useful because your package lets the user inspect the integration rules that were applied. I'm pretty sure that one of the most asked questions of users is "I need a list of steps that show how Mathematica solved this integration." On StackExchange, we usually don't have a satisfying answer to these questions. On several occasions, I had to literally fill pages when trying to repeat some integrations with pen and paper; always having the Abramowitz/Stegun ready when I hit a dead end.
- Your approach of having 70k+ test-cases that you can check is simply awesome. There is no better word to put. It is almost hilarious when you write on your website "Numerous individuals have helped make this website possible." You, who seemed to need help setting up a website uses, in my opinion, the only right approach from a software developer's perspective: Test-driven development with 70000 test cases. That just blows my mind.
Only through your work, we have an extensive database of integration rules that can be used virtually in any system, although we currently have it just in Mathematica code. I'm not sure if you are aware of this project, but Cory Walker is working on an open-source CAS that uses the same language as Mathematica which is called Expreduce. So while Cory only (!) had to implement the core system of replacement rules, he can now use Rubi's set of rules for integration.
I have some suggestions for Rubi to make it more accessible. After downloading, I looked at your code and these are the points jumped into my eye
- I could not find a license. This might seem to be no big deal, but indeed it is the bread and butter when you share your code because, for one, it tells people what they can and cannot do with your work. Secondly, if you want people to participate, a license is a must. For most of my software, I'm using the very open MIT license which leaves very much freedom to use my work even in a commercial product. You can look at choosealicense.com and just decide which one you like. After that, it is as easy as putting a
Licence.txt
in your package and maybe mention it on your website.
- At the moment, it seems not possible to use your package as a real package, which means putting it into the
Applications
folder and loading it with <<Rubi`
. It seems to rely on the absolute position of the example notebook you provide. However, from looking at your code, I expect the necessary change to be small. Your package could be turned into a paclet that can be installed and updated quickly. Paclets are the way how Wolfram distributes packages (and other data) nowadays, and we are currently exploring the possibility of managing a community paclet server for open source projects. With this, a package can easily be installed with e PacletInstall
command directly from Mathematica which makes it very convenient for the user.
- The above being said, let's assume you would accept help from other developers that provide some fixes for your code, then it would be best to share your code through GitHub which is used by virtually everyone nowadays. If you never worked with a concurrent versions system like git, it might take some time to get used to it. On the bright side, however, users and other developers can easily participate by sharing their code improvements or filing bug reports. I'm confident that there are very few individuals who can help you with the integration rules, but providing code to make the paclet work or pointing out bugs could be of great help.
If any of this is of interest, I encourage you to visit our Mathematica StackExchange chat-room and say hi. I'm sure that many would be delighted to see you around and we can discuss things; especially if you are thinking about making Rubi more visible. You can always ping me there by starting your message with @halirutan
and I will be notified.
Finally, here are some small comments on your code. As I said earlier, there is currently an error when you try to load your package, and the reason is this portion:
LoadRules[filename_String] :=
Module[{object},
object=PrintTemporary["Loading "<>filename<>".m..."];
Get[FileNameJoin[{NotebookDirectory[],filename<>".m"}]];
NotebookDelete[object];
Null]
NotebookDirectory
uses the directory of the current notebook and this fails as soon as your notebook is (a) not saved and (b) not in the directory of your package. The fix is easy when you use this undocumented function inside your Rubi.m
instead:
DirectoryName[System`Private`$InputFileName]
Because what you actually want is the directory-name where your Rubi.m
lives. Another thing that looks suspicious to me is in Integration utility functions.m
in line 289
InverseFunctionQ[u_] :=
LogQ[u] || InverseTrigQ[u] && Length[u]<=1 || InverseHyperbolicQ[u] || Head[u]===Mods || Head[u]===PolyLog
I might be wrong, but I cannot find any definition of Mods
inside your code and it seems you wanted to write Mod
. As a last minor point, inside the same file, you are defining many little helper functions like this
(* If u is a power, SumQ[u] returns True; else it returns False. *)
PowerQ[u_] := Head[u]===Power
Besides that the comment seems the wrong one, why not turn all these comments into a ::usage
message? It is good practice to have a usage message and there is no harm even to define them for internal functions. Additionally, it lets users quickly look-up what a function does when you used them