Monday, February 18, 2008

A Small Mathematical Project

Some times back I received an invitation to join an online community on Diophantine equations and related mathematical group in my Orkut account. I did not join the group for quite some time as I am very irregular in Orkut. But at last I when I wanted to join the group it is no longer there, this group’s moderator, a student of Indian Institute of Technology, wanted to run the community as complete mathematical community, unfortunately he decided to close the group.

When I learned about Diophantine equations in little details, I felt that how about writing a small common lisp utility to get going in this field. There were challenges to do that and more for a person like me who likes to work on his own code rather than using library in hobby projects. This post is all about what I felt during that development. I made a point of writing some lines while coding. Not as a comment but as a thought process.

How can I create a set (list) of values starting from one number and ending at another number? This question came to my mind first and the solution is writing a function which will give me a list like that on demand. It is intuitive that the arguments in this function would be a starting number, an end number and an incremental element which will increment the starting number till the end number or less. Moreover Diophantine equation demands that variables needs to integers.

(defun diophantine-create-set(start end)
(loop for n from start to end
while(<= n end) collect n))


Once I got that I have to think how I can represent a Diophantine equation in common lisp. The first thing that I felt is this has to be small so it will be a two unknown argument equation not an n-unknown Diophantine. At this point my imaginary linear Diophantine looked something like:
Ax + By = K

Here I have to get the constant values from the user. That is good enough but another step needs to be done in this, which re-writing the equation,

y = (K – Ax) / B

Once I got this form of the equation I can write something like:

(lambda (x)
(/ (- k (* a x)) b))

So now how do I do this? I have come with this macro:

(defmacro diophantine-equation (a b k s e)
`(mapcar #'(lambda(x) (/ (- ,k (* ,a x)) ,b)) (diophantine-create-set ,s ,e)))


Following are some evaluation of this macro:

CL-USER> (diophantine-equation 1 1 10 1 100)
(9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17
-18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36
-37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55
-56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74
-75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90)

CL-USER> (diophantine-equation 2 1 10 1 100)
(8 6 4 2 0 -2 -4 -6 -8 -10 -12 -14 -16 -18 -20 -22 -24 -26 -28 -30 -32 -34 -36
-38 -40 -42 -44 -46 -48 -50 -52 -54 -56 -58 -60 -62 -64 -66 -68 -70 -72 -74
-76 -78 -80 -82 -84 -86 -88 -90 -92 -94 -96 -98 -100 -102 -104 -106 -108 -110
-112 -114 -116 -118 -120 -122 -124 -126 -128 -130 -132 -134 -136 -138 -140
-142 -144 -146 -148 -150 -152 -154 -156 -158 -160 -162 -164 -166 -168 -170
-172 -174 -176 -178 -180 -182 -184 -186 -188 -190)


Looks fine till now but see what you get from the following evaluation:


CL-USER> (diophantine-equation 2 5 10 1 100)
(8/5 6/5 4/5 2/5 0 -2/5 -4/5 -6/5 -8/5 -2 -12/5 -14/5 -16/5 -18/5 -4 -22/5
-24/5 -26/5 -28/5 -6 -32/5 -34/5 -36/5 -38/5 -8 -42/5 -44/5 -46/5 -48/5 -10
-52/5 -54/5 -56/5 -58/5 -12 -62/5 -64/5 -66/5 -68/5 -14 -72/5 -74/5 -76/5
-78/5 -16 -82/5 -84/5 -86/5 -88/5 -18 -92/5 -94/5 -96/5 -98/5 -20 -102/5
-104/5 -106/5 -108/5 -22 -112/5 -114/5 -116/5 -118/5 -24 -122/5 -124/5 -126/5
-128/5 -26 -132/5 -134/5 -136/5 -138/5 -28 -142/5 -144/5 -146/5 -148/5 -30
-152/5 -154/5 -156/5 -158/5 -32 -162/5 -164/5 -166/5 -168/5 -34 -172/5 -174/5
-176/5 -178/5 -36 -182/5 -184/5 -186/5 -188/5 -38)


Now the main aim of diophantine equations is failing, as only the integer solutions are accepted as per Diophantine analysis. In the last evaluation we have some integer solution but this list has both integers as well as fractions. This to me is simply “Not acceptable!”
Moreover I can bet that it will not be acceptable in mathematics community.


At this point of development I had to put some more code in my diophantine-equation macro, it has to check whether a solution is integer or not. I will map the list and create a list of solutions with integers if it exists. To achieve this I introduced another macro because I wanted to keep diophantine-equation macro as it is. Here is the macro:

(defmacro diophantine-solutions(a b k s e)
`(remove nil (mapcar #'(lambda(x)
(when (integerp x)
x))
(diophantine-equation ,a ,b ,k ,s ,e))))


Let’s see what kind of output I have from this macro:

CL-USER> (diophantine-solutions 2 5 10 1 100)
(0 -2 -4 -6 -8 -10 -12 -14 -16 -18 -20 -22 -24 -26 -28 -30 -32 -34 -36 -38)

Now as we have built this basic framework for Diophantine analysis, let’s put this to some test. I know that I may not be able to answer a lot of questions asked in Diophantine analysis. But this small framework can answer a basic question right now. The first question that is asked in Diophantine analysis is, “Are there any solutions?” of course I have to reframe the question as per my framework as “Are there any solution between the range that I have mentioned?” it looks something like this in the REPL.

CL-USER> (if (eq nil (diophantine-solutions 2 5 10 1 100))
nil
t)
T
CL-USER> (if (eq nil (diophantine-solutions 2 5 10 1 4))
nil
t)
NIL
CL-USER> (if (eq nil (diophantine-solutions 2 5 10 1 1))
nil
t)
NIL
CL-USER> (if (eq nil (diophantine-solutions 2 5 10 1 10))
nil
t)
T

This utility has only one function and two macros.

I hope you like this blog; however if you think that there is a better way (which I am sure would be) of doing some things that I have done here or if you find any bug please feel free comment on it.

Thanks for reading.

Disclaimer: This is a hobby project not for any production use.

No comments: