I understand the complexities when using binary (or binaryoid) floating point and representing the result in decimal:
1 (do ((numerator 1 (* 10 numerator)))
2 ((>= numerator 1000000000000))
3 (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
4 (prin1 fred)
5 (princ " ")
6 (prin1 (eval fred))
7 (terpri)))
(COERCE 1/3 'DOUBLE-FLOAT) 0.3333333333333333d0
(COERCE 10/3 'DOUBLE-FLOAT) 3.3333333333333335d0
(COERCE 100/3 'DOUBLE-FLOAT) 33.333333333333336d0
(COERCE 1000/3 'DOUBLE-FLOAT) 333.3333333333333d0
(COERCE 10000/3 'DOUBLE-FLOAT) 3333.3333333333335d0
(COERCE 100000/3 'DOUBLE-FLOAT) 33333.333333333336d0
(COERCE 1000000/3 'DOUBLE-FLOAT) 333333.3333333333d0
(COERCE 10000000/3 'DOUBLE-FLOAT) 3333333.3333333335d0
(COERCE 100000000/3 'DOUBLE-FLOAT) 3.3333333333333332d7
(COERCE 1000000000/3 'DOUBLE-FLOAT) 3.333333333333333d8
(COERCE 10000000000/3 'DOUBLE-FLOAT) 3.3333333333333335d9
(COERCE 100000000000/3 'DOUBLE-FLOAT) 3.3333333333333332d10
But I wish to avoid the infelicity of that final varying digit. Speed of computation is not important for me in this situation.
Do there exist any true decimal floating point LISP packages out there?
Edit 1: Ideally, this package would allow for arbitrary precision, as bignum does for integers.
Edit 2, in response to Dennis Jaheruddin's question:
[I]f you are not interested in the final digit but just want the
numbers to be the same, you might just want to observe the first 15 or
so digits?
I thought of that. It won't work. In the case of 2/3, for example, I'd want something like 666667. What I see is this:
1 (do ((numerator 2 (* 10 numerator)))
2 ((>= numerator 1000000000000))
3 (let ((fred (list 'coerce (/ numerator 3) (quote 'double-float))))
4 (prin1 fred)
5 (princ " ")
6 (prin1 (eval fred))
7 (terpri)))
(COERCE 2/3 'DOUBLE-FLOAT) 0.6666666666666666d0
(COERCE 20/3 'DOUBLE-FLOAT) 6.666666666666667d0
(COERCE 200/3 'DOUBLE-FLOAT) 66.66666666666667d0
(COERCE 2000/3 'DOUBLE-FLOAT) 666.6666666666666d0
(COERCE 20000/3 'DOUBLE-FLOAT) 6666.666666666667d0
(COERCE 200000/3 'DOUBLE-FLOAT) 66666.66666666667d0
(COERCE 2000000/3 'DOUBLE-FLOAT) 666666.6666666666d0
(COERCE 20000000/3 'DOUBLE-FLOAT) 6666666.666666667d0
(COERCE 200000000/3 'DOUBLE-FLOAT) 6.6666666666666664d7
(COERCE 2000000000/3 'DOUBLE-FLOAT) 6.666666666666666d8
(COERCE 20000000000/3 'DOUBLE-FLOAT) 6.666666666666667d9
(COERCE 200000000000/3 'DOUBLE-FLOAT) 6.6666666666666664d10
As you can see, I can't even use the final digit to determine whether to round up; 64 rounds to 60, not 70. But I could discard the final digit and use the previous digit to round the rest of the number. I'm uncomfortable with this, though, because (a) I'm beginning to discard a lot of precision by this point, and (b) I'm not sure that there aren't cases where this would cause rounding the wrong way. A decimal floating point package, preferably with arbitrary precision, would be ideal.
Edit 3: As Rainer Joswig points out in his answer below, a non-portable potential solution would be to set the floating point precision. For those following along at home, he points out here that this is done thus: (SETF (EXT:LONG-FLOAT-DIGITS) n)
Edit 4: In the comments after his answer, Rainer Joswig recommends looking into the algebra systems Maxima and Axiom. Doing so leads to these excellent Wikipedia resources:
the article Mathematical software
the article Comparison of computer algebra systems
that article's See also section
that article's External links section, most of which links point to lists of software
Edit 5: I have since determined that I do not need a decimal floating point package, but I'm still curious as to whether there is one. Probably there isn't.
Why don't I need one? The answer is a combination of (a) Rainer Joswig's pointer to the wu-decimal package and (b) wvxvw's mention of long division.
Although wu-decimal doesn't have the conventional characteristic and mantissa using base 10, it does introduce an intriguing idea: storing numbers as ratios. So 1/3 is stored as 1/3, not a repeating (for a finite length) binary fraction. Although multiplying numbers stored as ratios can soon yield quite lengthy ratios, the original precision is maintained throughout. I'm going to use that idea. What I don't need is wu-decimal's quite nifty parsing and writing of ratios as decimal numbers when appropriate, so I won't be installing the package. If you're interested in making easy the parsing and writing of such values, check out the package. (I haven't used it.)
What remains, then, is the printing of ratios as decimal numbers. For this I'll be using long division, just as wvxvw does. My code is somewhat different, but for the long division idea, I owe him many thanks.
Never used it:
http://wukix.com/lisp-decimals
In GNU CLISP you can set the float precision.
Related
I'm learning Clojure and started by copying the functionality of a Python program that would create genomic sequences by following an (extremely simple) Hidden Markov model.
In the beginning I stuck with my known way of serial programming and used the def keyword a lot, thus solving the problem with tons of side effects, kicking almost every concept of Clojure right in the butt. (although it worked as supposed)
Then I tried to convert it to a more functional way, using loop, recur, atom and so on. Now when I run I get an ArityException, but I can't read the error message in a way that shows me even which function throws it.
(defn create-model [name pA pC pG pT pSwitch]
; converts propabilities to cumulative prop's and returns a char
(with-meta
(fn []
(let [x (rand)]
(if (<= x pA)
\A
(if (<= x (+ pA pC))
\C
(if (<= x (+ pA pC pG))
\G
\T))))) ; the function object
{:p-switch pSwitch :name name})) ; the metadata, used to change model
(defn create-genome [n]
; adds random chars from a model to a string and switches models randomly
(let [models [(create-model "std" 0.25 0.25 0.25 0.25 0.02) ; standard model, equal props
(create-model "cpg" 0.1 0.4 0.4 0.1 0.04)] ; cpg model
islands (atom 0) ; island counter
m (atom 0)] ; model index
(loop [result (str)]
(let [model (nth models #m)]
(when (< (rand) (:p-switch (meta model))) ; random says "switch model!"
; (swap! m #(mod (inc #m) 2)) ; swap model used in next iteration
(swap! m #(mod (inc %) 2)) ; EDIT: correction
(if (= #m 1) ; on switch to model 1, increase island counter
; (swap! islands #(inc #islands)))) ; EDIT: my try, with error
(swap! islands inc)))) ; EDIT: correction
(if (< (count result) n) ; repeat until result reaches length n
(recur (format "%s%c" result (model)))
result)))))
Running it works, but calling (create-genome 1000) leads to
ArityException Wrong number of args (1) passed to: user/create-genome/fn--772 clojure.lang.AFn.throwArity (AFn.java:429)
My questions:
(obviously) what am I doing wrong?
how exactly do I have to understand the error message?
Information I'd be glad to receive
how can the code be improved (in a way a clojure-newb can understand)? Also different paradigms - I'm grateful for suggestions.
Why do I need to put pound-signs # before the forms I use in changing the atoms' states? I saw this in an example, the function wouldn't evaluate without it, but I don't understand :)
Since you asked for ways to improve, here's one approach I often find myself going to : Can I abstract this loop into a higher order pattern?
In this case, your loop is picking characters at random - this can be modelled as calling a fn of no arguments that returns a character - and then accumulating them together until it has enough of them. This fits very naturally into repeatedly, which takes functions like that and makes lazy sequences of their results to whatever length you want.
Then, because you have the entire sequence of characters all together, you can join them into a string a little more efficiently than repeated formats - clojure.string/join should fit nicely, or you could apply str over it.
Here's my attempt at such a code shape - I tried to also make it fairly data-driven and that may have resulted in it being a bit arcane, so bear with me:
(defn make-generator
"Takes a probability distribution, in the form of a map
from values to the desired likelihood of that value appearing in the output.
Normalizes the probabilities and returns a nullary producer fn with that distribution."
[p-distribution]
(let[sum-probs (reduce + (vals p-distribution))
normalized (reduce #(update-in %1 [%2] / sum-probs) p-distribution (keys p-distribution) )]
(fn [] (reduce
#(if (< %1 (val %2)) (reduced (key %2)) (- %1 (val %2)))
(rand)
normalized))))
(defn markov-chain
"Takes a series of states, returns a producer fn.
Each call, the process changes to the next state in the series with probability :p-switch,
and produces a value from the :producer of the current state."
[states]
(let[cur-state (atom (first states))
next-states (atom (cycle states))]
(fn []
(when (< (rand) (:p-switch #cur-state))
(reset! cur-state (first #next-states))
(swap! next-states rest))
((:producer #cur-state)))))
(def my-states [{:p-switch 0.02 :producer (make-generator {\A 1 \C 1 \G 1 \T 1}) :name "std"}
{:p-switch 0.04 :producer (make-generator {\A 1 \C 4 \G 4 \T 1}) :name "cpg"}])
(defn create-genome [n]
(->> my-states
markov-chain
(repeatedly n)
clojure.string/join))
To hopefully explain a little of the complexity:
The let in make-generator is just making sure the probabilities sum to 1.
make-generator makes heavy use of another higher-order looping pattern, namely reduce. This essentially takes a function of 2 values and threads a collection through it. (reduce + [4 5 2 9]) is like (((4 + 5) + 2) + 9). I chiefly use it to do a similar thing to your nested ifs in create-model, but without naming how many values are in the probability distribution.
markov-chain makes two atoms, cur-state to hold the current state and next-states, which holds an infinite sequence (from cycle) of the next states to switch to. This is to work like your m and models, but for arbitrary numbers of states.
I then use when to check if the random state switch should occur, and if it does perform the two side effects I need to keep the state atoms up to date. Then I just call the :producer of #cur-state with no arguments and return that.
Now obviously, you don't have to do this exactly this way, but looking for those patterns certainly does tend to help me.
If you want to go even more functional, you could also consider moving to a design where your generators take a state (with seeded random number generator) and return a value plus a new state. This "state monad" approach would make it possible to be fully declarative, which this design isn't.
Ok, it's a long shot, but it looks like your atom-updating functions:
#(mod (inc #m) 2)
and
#(inc #islands)
are of 0-arity, and they should be of arity at least 1.
This leads to the answer to your last question: the #(body) form is a shortcut for (fn [...] (body)). So it creates an anonymous function.
Now the trick is that if body contains % or %x where x is a number, the position where it appears will be substituted for the referece to the created function's argument number x (or the first argument if it's only %).
In your case that body doesn't contain references to the function arguments, so #() creates an anonymous function that takes no arguments, which is not what swap! expects.
So swap tries to pass an argument to something that doesn't expect it and boom!, you get an ArityException.
What you really needed in those cases was:
(swap! m #(mod (inc %) 2)) ; will swap value of m to (mod (inc current-value-of-m) 2) internally
and
(swap! islands inc) ; will swap value of islands to (inc current-value-of-islands) internally
respectively
Your mistake has to do with what you asked about the hashtag macro #.
#(+ %1 %2) is shorthand for (fn [x y] (+ x y)). It can be without arguments too: #(+ 1 1). That's how you are using it. The error you are getting is because swap! needs a function that accepts a parameter. What it does is pass the atom's current value to your function. If you don't care about its state, use reset!: (reset! an-atom (+ 1 1)). That will fix your error.
Correction:
I just took a second look at your code and realised that you are actually using working on the atoms' states. So what you want to do is this:
(swap! m #(mod (inc %) 2)) instead of (swap! m #(mod (inc #m) 2)).
As far as style goes, you are doing good. I write my functions differently every day of the week, so maybe I'm not one to give advice on that.
Hi I am a bit new to Clojure/Lisp programming but I have used recursion before in C like languages, I have written the following code to sum all numbers that can be divided by three between 1 to 100.
(defn is_div_by_3[number]
(if( = 0 (mod number 3))
true false)
)
(defn sum_of_mult3[step,sum]
(if (= step 100)
sum
)
(if (is_div_by_3 step)
(sum_of_mult3 (+ step 1 ) (+ sum step))
)
)
My thought was to end the recursion when step reaches sum, then I would have all the multiples I need in the sum variable that I return, but my REPL seems to returning nil for both variables what might be wrong here?
if is an expression not a statement. The result of the if is always one of the branches. In fact Clojure doesn't have statements has stated here:
Clojure programs are composed of expressions. Every form not handled specially by a special form or macro is considered by the compiler to be an expression, which is evaluated to yield a value. There are no declarations or statements, although sometimes expressions may be evaluated for their side-effects and their values ignored.
There is a nice online (and free) book for beginners: http://www.braveclojure.com
Other thing, the parentheses in Lisps are not equivalent to curly braces in the C-family languages. For example, I would write your is_div_by_3 function as:
(defn div-by-3? [number]
(zero? (mod number 3)))
I would also use a more idiomatic approach for the sum_of_mult3 function:
(defn sum-of-mult-3 [max]
(->> (range 1 (inc max))
(filter div-by-3?)
(apply +)))
I think that this code is much more expressive in its intention then the recursive version. The only trick thing is the ->> thread last macro. Take a look at this answer for an explanation of the thread last macro.
There are a few issues with this code.
1) Your first if in sum_of_mult3 is a noop. Nothing it returns can effect the execution of the function.
2) the second if in sum_of_mult3 has only one condition, a direct recursion if the step is a multiple of 3. For most numbers the first branch will not be taken. The second branch is simply an implicit nil. Which your function is guaranteed to return, regardless of input (even if the first arg provided is a multiple of three, the next recurred value will not be).
3) when possible use recur instead of a self call, self calls consume the stack, recur compiles into a simple loop which does not consume stack.
Finally, some style issues:
1) always put closing parens on the same line with the block they are closing. This makes Lisp style code much more readable, and if nothing else most of us also read Algol style code, and putting the parens in the right place reminds us which kind of language we are reading.
2) (if (= 0 (mod number 3)) true false) is the same as (= 0 (mod number 3) which in turn is identical to (zero? (mod number 3))
3) use (inc x) instead of (+ x 1)
4) for more than two potential actions, use case, cond, or condp
(defn sum-of-mult3
[step sum]
(cond (= step 100) sum
(zero? (mod step 3)) (recur (inc step) (+ sum step))
:else (recur (inc step) sum))
In addition to Rodrigo's answer, here's the first way I thought of solving the problem:
(defn sum-of-mult3 [n]
(->> n
range
(take-nth 3)
(apply +)))
This should be self-explanatory. Here's a more "mathematical" way without using sequences, taking into account that the sum of all numbers up to N inclusive is (N * (N + 1)) / 2.
(defn sum-of-mult3* [n]
(let [x (quot (dec n) 3)]
(* 3 x (inc x) 1/2)))
Like Rodrigo said, recursion is not the right tool for this task.
I was wondering if there was a way to take a list of numbers (digits), and truncate the numbers together to be one large number (not addition) in Scheme. For example, I would want
(foo '(1 2 3 4))
;=> 1234
Does Scheme have a built in function to do this?
There are a number of languages that are in the Scheme family, and there are a few versions of Scheme, too. If you're using one, e.g., Racket, that includes a left associative fold (often called foldl, fold, or reduce, though there are other variations, too), this is pretty straightfoward to implement in terms of the fold. Folds have been described in more detail in these questions and answers:
Finding maximum distance between two points in a list (scheme) This question includes a description of how fold can be viewed as an iterative construct (and in Scheme, which mandates tail call optimization, is compiled to iterative code), and also includes an implementation of foldl for Schemes that don't have it.
Flattening a List of Lists This question is about a somewhat unusual fold, and how it (or a standard fold) can be used to flatten a list.
scheme structures and lists This question has an example of how you might adjust the function that you pass to a fold to achieve slightly different behavior. (I also include an opinionated (but true ;), I assure you) comment about how Common Lisp's reduce provides a somewhat more convenient interface than what's provided in some of the Scheme libraries.
Here's what the code looks like in terms of foldl:
(define (list->num digits)
(foldl (lambda (digit n)
(+ (* 10 n) digit))
0
digits))
> (list->num '(1 2 3 4))
1234
If your language doesn't have it, foldl is pretty easy to write (e.g., my answer to the one of the questions above includes an implementation) and use the preceding code, or you can write the whole function (using the same approach) yourself:
(define (list->num-helper digits number-so-far)
(if (null? digits)
number-so-far
(list->num-helper (cdr digits)
(+ (* 10 number-so-far)
(car digits)))))
(define (list->num digits)
(list->num-helper digits 0))
You can make that a bit more concise by using a named let:
(define (list->num digits)
(let l->n ((digits digits)
(number 0))
(if (null? digits)
number
(l->n (cdr digits)
(+ (* 10 number)
(car digits))))))
I read a lot of documentation about Clojure (and shall need to read it again) and read several Clojure questions here on SO to get a "feel" of the language. Besides a few tiny functions in elisp I've never written in any Lisp language before. I wrote my first project Euler solution in Clojure and before going further I'd like to better understand something about map and reduce.
Using a lambda, I ended up with the following (to sum all multiple of either 3 or 5 or both between 1 and 1000 inclusive):
(reduce + (map #(if (or (= 0 (mod %1 3)) (= 0 (mod %1 5))) %1 0) (range 1 1000)))
I put it on one line because I wrote it on the REPL (and it gives the correct solution).
Without the lambda, I wrote this:
(defn val [x] (if (or (= 0 (mod x 3)) (= 0 (mod x 5))) x 0))
And then I compute the solution doing this:
(reduce + (map val (range 1 1000)))
In both cases, my question concerns what the map should return, before doing the reduce. After doing the map I noticed I ended up with a list looking like this: (0 0 3 0 5 6 ...).
I tried removing the '0' at the end of the val definition but then I received a list made of (nil nil 3 nil 5 6 etc.). I don't know if the nil are an issue or not. I figured out that I was going to sum while doing a fold-left anyway so that the zero weren't really an issue.
But still: what's a sensible map to return? (0 0 3 0 5 6 ...) or (nil nil 3 nil 5 6...) or (3 5 6 ...) (how would I go about this last one?) or something else?
Should I "filter out" the zeroes / nils and if so how?
I know I'm asking a basic question but map/reduce is obviously something I'll be using a lot so any help is welcome.
It sounds like you already have an intuative undestanding of the need to seperate mapping concerns form the reducing It's perfectly natural to have data produced by map that is not used by the reduce. infact using the fact that zero is the identity value for addition make this even more elegant.
mappings job is to produce the new data (in this case 3 5 or "ignore")
reduces job is to decide what to include and to produce the final result.
what you started with is idiomatic clojure and there is no need to complicate it any more,
so this next example is just to illustrate the point of having map decide what to include:
(reduce #(if-not (zero? %1) (+ %1 %2) %2) (map val (range 10)))
in this contrived example the reduce function ignores the zeros. In typical real world code if the idea was as simple as filtering out some value then people tend to just use the filter function
(reduce + (filter #(not (zero? %)) (map val (range 10))))
you can also just start with filter and skip the map:
(reduce + (filter #(or (zero? (rem % 3)) (zero? (rem % 5))) (range 10)))
The watchword is clarity.
Use filter, not map. Then you don't have to choose a null
value that you later have to decide not to act on.
Naming the filtering/mapping function can help. Do so with let
or letfn, not defn, unless you have use for the function elsewhere.
Acting on this advice brings us to ...
(let [divides-by-3-or-5? (fn [n] (or (zero? (mod n 3)) (zero? (mod n 5))))]
(reduce + (filter divides-by-3-or-5? (range 1 1000))))
You may want to stop here for now.
This reads well, but the divides-by-3-or-5? function sticks in the throat. Change the factors and we need a completely new function. And that repeated phrase (zero? (mod n ...)) jars. So ...
We want a function, that - given a list (or other collection) of possible factors - tells us whether any of them apply to a given number. In other words, we want
a function of a collection of numbers - the possible factors - ...
that returns a function of one number - the candidate - ...
that tells us whether the candidate is divisible by any of the possible factors.
One such function is
(fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))
... which we can employ thus
(let [divides-by-any? (fn [ns] (fn [n] (some (fn [x] (zero? (mod n x))) ns)))]
(reduce + (filter (divides-by-any? [3 5]) (range 1 1000))))
Notes
This "improvement" has made the program a little slower.
divides-by-any? might prove useful enough to be promoted to a
defn.
If the operation were critical, you could consider stripping out
redundant factors. For example [2 3 6] could be reduced to [6].
If the operation were really critical, and the factors were supplied
as constants, you could consider creating the filter function with a
macro that went back to using or.
This is a bit of a shaggy-dog story, but it recounts the thoughts prompted by the problem you refer to.
In your case I would use keep instead of map. It is similar to map except that it keeps only the non-nil values.
I am playing around with lisp's format function, but I have hit a snag because although I can get it to write the list of numbers aligned nicely, I can't seem to get it to zero pad it:
(defun inc (a) (+ 1 a))
(dotimes (i 10)
(format t "~3#:D ~:*~R~%" (inc i)))
This produces the following output:
+1: one
+2: two
+3: three
+4: four
+5: five
+6: six
+7: seven
+8: eight
+9: nine
+10: ten
Does anybody know how to get it to be zero-padded?
Example lifted from the PCL chapter on FORMAT:
(format nil "~12d" 1000000) ==> " 1000000"
(format nil "~12,'0d" 1000000) ==> "000001000000"