Nested Let in Anglican Clojure - clojure

I am new to Anglican, the Probabilistic programming language in Clojure. I am trying to use a nested let construct in Clojure.
The following defqueryruns without any issues.
(defquery panda3 [p1]
(let [p2 (sample
(categorical
{:speA (/ 1 2),
:speB (/ 1 2)}))]
(if (= p2 :speA)
( let [p3 (sample
(categorical
{:twins (/ 1 10),
:notwins (/ 9 10)}))]
)
( let [p3 (sample
(categorical
{:twins (/ 2 10),
:notwins (/ 8 10)}))]
))
p2))
However, instead of returning the value of p2 at the end, if I try to return the value of p3, it returns errors.
(defquery panda3 [p1]
(let [p2 (sample
(categorical
{:speA (/ 1 2),
:speB (/ 1 2)}))]
(if (= p2 :speA)
( let [p3 (sample
(categorical
{:twins (/ 1 10),
:notwins (/ 9 10)}))]
)
( let [p3 (sample
(categorical
{:twins (/ 2 10),
:notwins (/ 8 10)}))]
))
p3))
The idea is to assign p3 based on the outcome of p2. However, I am unable to do so. What am I doing wrong?
Thanks in advance,

As the comment said, you need to return p3 from within the scope of the let in which it is defined:
(defquery panda3 [p1]
(let [p2 (sample
(categorical
{:speA (/ 1 2),
:speB (/ 1 2)}))]
(if (= p2 :speA)
(let [p3 (sample
(categorical
{:twins (/ 1 10),
:notwins (/ 9 10)}))]
p3)
(let [p3 (sample
(categorical
{:twins (/ 2 10),
:notwins (/ 8 10)}))]
p3 ))))
Update
As amalloy points out, the 2nd part could be:
; return the result of `(sample (categorical ...))` called
; with one of the 2 maps
(if (= p2 :speA)
(sample
(categorical
{:twins (/ 1 10),
:notwins (/ 9 10)} ))
(sample
(categorical
{:twins (/ 2 10),
:notwins (/ 8 10)} )))
or even
; return the result of `(sample (categorical ...))` called
; with one of the 2 maps
(sample
(categorical
(if (= p2 :speA)
{:twins (/ 1 10),
:notwins (/ 9 10)}
{:twins (/ 2 10),
:notwins (/ 8 10)} )))

Related

Making blocks of matrix (represented by list) in racket

I have a task where I need to divide the given matrix into blocks (width and height are also given and suite the matrix). The metrix is represented by a list of lists, where every list is a row in the matrix.
For example
'(( 1 2 3 4)
( 5 6 7 8)
( 9 10 11 12)
(13 14 15 16))
for given width=height=2 the blocks should be (1 2 5 6), (3 4 7 8), (9 10 13 14), (11 12 15 16).
Can you please help me with it?
I have trind to split it by height and width, then traverse and append lists, but it doenst work att all, I have no idea how the algorithm should work.
You can try this code- it works, but it seems a little bit convoluted, so maybe there is some better way:
(define (partition-by n lst)
(if (null? lst) lst
(cons (take lst n)
(partition-by n (drop lst n)))))
(define (chunk lst w)
(map (lambda (group) (partition-by w group))
lst))
(define (matrix->blocks matrix w h)
(apply append
(for/list ((row (partition-by w (chunk matrix w))))
(partition-by (* w h) (flatten (apply map list row))))))
Test:
(define m '((1 2 3 4) (5 6 7 8) (9 10 11 12) (13 14 15 16)))
(matrix->blocks m 2 2)
=> '((1 2 5 6) (3 4 7 8) (9 10 13 14) (11 12 15 16))
This answer takes width and height to refer to block dimensions, and builds a matrix of blocks
(each block is a list of rows like the input, so result is a rank 4 list;
if less nesting is required flattens can be inserted appropriately).
Plan: convert input to flat vector, fetch elements in correct order to build result.
#lang racket
(require test-engine/racket-tests)
(define (matrix->matrixes lor w h) ;; (ListOf ListOfX) Natural Natural -> (ListOf (ListOf (ListOf ListOfX)))
;; produce matrix of blocks of size w x h from matrix lor, which is a list of rows
;; each block is (* w h) elements (list of h lists of length w)
;; eg (define M32 '((1 2) (3 4) (5 6))) ; 3 rows, 2 cols
;; (matrix->matrixes M32 2 1) => ( ( ((1 2)) ) ( ((3 4)) ) ( ((5 6)) ) )
;; (matrix->matrixes M32 1 3) => ( ( ((1) (3) (5)) ((2) (4) (6)) ) )
(let* ( [v (list->vector (flatten lor))]
[nr (length lor)] ;; n original rows
[nc (length (car lor))] ;; n original cols
[nrb (/ nr h)] ;; n rows of blocks
[ncb (/ nc w)]) ;; n cols of blocks
(build-list nrb (lambda (brx)
(build-list ncb (lambda (bcx)
(build-list h (lambda (hx)
(build-list w (lambda (wx)
(vector-ref v (+ (* brx (* ncb h w)) (* bcx w) (* hx nc) wx))))))))))))
(define M32 '((1 2) (3 4) (5 6)))
(define M44 '((1 2 3 4) (5 6 7 8) (9 10 11 12) (13 14 15 16)))
(check-expect (matrix->matrixes M32 2 1) '( ( ((1 2)) ) ( ((3 4)) ) ( ((5 6)) ) ) )
(check-expect (matrix->matrixes M32 1 3) '( ( ((1) (3) (5)) ((2) (4) (6)) ) ) )
(check-expect (matrix->matrixes M44 4 4) `(( ,M44 )))
(matrix->matrixes M44 2 2)
(test)

Iterate over a list with a given step in clojure

I'm trying to iterate over a list with a given step in clojure.
In python I would have done the following :
xs = list(range(10))
xs[::2]
# out: [0, 2, 4, 6, 8]
xs[1::2]
# out: [1, 3, 5, 7, 9]
I can't figure out a clojure solution that feels idiomatic.
Here is the best I can think of:
(defn iterate-step-2 [xs]
(map first (take-while some? (iterate nnext xs))))
(iterate-step-2 (range 10))
; out: (0 2 4 6 8)
(iterate-step-2 (rest (range 10)))
; out: (1 3 5 7 9)
But it's not as generic (step is not configurable) and as flexible as the python solution. Plus it seems overly complicated.
Is there a better way to do this ?
You can use take-nth for this:
user=> (take-nth 2 (range 10))
(0 2 4 6 8)
user=> (take-nth 2 (rest (range 10)))
(1 3 5 7 9)
;; equivalent to Python's your_seq[1:7:2] would be:
(->> your-seq (drop 1) (take 7) (take-nth 2))
;; equivalent to Python's your_seq[::2] would be:
(->> your-seq (take-nth 2))
;; equivalent to Python's your_seq[2:4:-3] would be:
(->> your-seq (take 4) (drop 2) (reverse) (take-nth 3))
;; equivalent to Python's your_seq[2:-4:-1]:
(->> your-seq (take (+ 1 (- (length your-seq) 4))) (drop 2) (reverse))
Another option is to generate the desired index values, and then use those for the lookup:
(let [N 10
data (vec (range N)) ; `vec` is optional but faster than using (lazy) list if large N
idxs (range 1 10 2)
result (mapv #(nth data %) idxs)]
)
with result:
N => 10
data => [0 1 2 3 4 5 6 7 8 9]
idxs => (1 3 5 7 9)
result => [1 3 5 7 9]
or something less simple:
(let [N 9999
data (vec (range N)) ; `vec` is optional but faster than using (lazy) list if large N
idxs (mapv #(Math/pow 2 %) (range 11))
result (mapv #(nth data %) idxs)]
with result:
idxs => [1.0 2.0 4.0 8.0 16.0 32.0 64.0 128.0 256.0 512.0 1024.0]
result => [1 2 4 8 16 32 64 128 256 512 1024]
Interesting! Apparently nth will accept a floating-point index value as long as it has a zero fraction. :)

`for` as a function instead of a macro [duplicate]

This question already has answers here:
Cartesian product in clojure
(6 answers)
Closed 2 years ago.
I'd like to have a forall function that acts like for but takes a list of sequences as inputs.
(forall (fn [arr]
(prn arr))
(range 10)
(range 10)
(range 10))
=>
; [0 0 0]
; [0 0 1]
; [0 0 2]
; ....
; [9 9 9]
Is there a good way to write this?
I suppose you want to map over the cartesian product of the input sequences, right? If so, you can create a lazy sequence of the cartesian product using for example the clojure.math.combinatorics/cartesian-product function from the clojure.math.combinatorics library and then map over that.
(defn forall [f & seqs]
(map f (apply clojure.math.combinatorics/cartesian-product seqs)))
This is a function that works more or less like the for macro when there are multiple sequences. Here is an example of calling it, and the result that you would obtain:
(forall (fn [arr]
[:element arr])
(range 3)
(range 3)
(range 3))
;; => ([:element (0 0 0)] [:element (0 0 1)] [:element (0 0 2)] [:element (0 1 0)] [:element (0 1 1)] [:element (0 1 2)] [:element (0 2 0)] [:element (0 2 1)] [:element (0 2 2)] [:element (1 0 0)] [:element (1 0 1)] [:element (1 0 2)] [:element (1 1 0)] [:element (1 1 1)] [:element (1 1 2)] [:element (1 2 0)] [:element (1 2 1)] [:element (1 2 2)] [:element (2 0 0)] [:element (2 0 1)] [:element (2 0 2)] [:element (2 1 0)] [:element (2 1 1)] [:element (2 1 2)] [:element (2 2 0)] [:element (2 2 1)] [:element (2 2 2)])
Note that in your example code, you call the prn function which is side-effectful, whereas the for-macro produces a lazy sequence. Combining laziness with side-effects is often discouraged because the side-effect may not happen when you would expect it to happen unless you know how lazy sequences work.
If you don't want to pull in the clojure.math.combinatorics library, you can easily implement your own cartesian product function, e.g.
(defn cart2 [a b]
(for [x a
y b]
(conj x y)))
(defn my-cartesian-product [& arrs]
(reduce cart2 [[]] arrs))

Mysterious Clojure function

I would like to write a clojure function that has the following behaviour :
(take 4 (floyd))
=> '((1) (2 3) (4 5 6) (7 8 9 10))
(take 3 (floyd))
=> '((1) (2 3) (4 5 6))
(take 1 (floyd))
=> '((1)))
I tried using partition and partition-all to validate these tests however i couldn't get the right solution. If you have any idea of how to do it, i would really appreciate a little help. I started using clojure a few weeks ago and still have some issues.
Thanks
Here's another option:
(defn floyd []
(map (fn [lo n] (range lo (+ lo n 1)))
(reductions + 1 (iterate inc 1))
(range)))
(take 5 (floyd))
;=> ((1) (2 3) (4 5 6) (7 8 9 10) (11 12 13 14 15))
This was arrived at based on the observation that you want a series of increasing ranges (the (range) argument to map is used to produce a sequence of increasingly longer ranges), each one starting from almost the triangular number sequence:
(take 5 (reductions + 0 (iterate inc 1)))
;=> (0 1 3 6 10)
If we start that sequence from 1 instead, we get the starting numbers in your desired sequence:
(take 5 (reductions + 1 (iterate inc 1)))
;=> (1 2 4 7 11)
If the + 1 inside the mapped function bothers you, you could do this instead:
(defn floyd []
(map (fn [lo n] (range lo (+ lo n)))
(reductions + 1 (iterate inc 1))
(iterate inc 1)))
it is not possible to solve it with partition / partition-all, since they split your sequence into predefined size chunks.
What you can do, is to employ recursive lazy function for that:
user> (defn floyd []
(letfn [(f [n rng]
(cons (take n rng)
(lazy-seq (f (inc n) (drop n rng)))))]
(f 1 (iterate inc 1))))
#'user/floyd
user> (take 1 (floyd))
;;=> ((1))
user> (take 2 (floyd))
;;=> ((1) (2 3))
user> (take 3 (floyd))
;;=> ((1) (2 3) (4 5 6))
user> (take 4 (floyd))
;;=> ((1) (2 3) (4 5 6) (7 8 9 10))
another variant can use similar approach, but only track chunk-start/chunk-size:
user> (defn floyd []
(letfn [(f [n start]
(cons (range start (+ start n))
(lazy-seq (f (inc n) (+ start n)))))]
(f 1 1)))
another approach is to use clojure's collection operating functions:
user> (defn floyd-2 []
(->> [1 1]
(iterate (fn [[start n]]
[(+ n start) (inc n)]))
(map (fn [[start n]] (range start (+ start n))))))
#'user/floyd-2
user> (take 4 (floyd-2))
;;=> ((1) (2 3) (4 5 6) (7 8 9 10))
user> (take 5 (floyd-2))
;;=> ((1) (2 3) (4 5 6) (7 8 9 10) (11 12 13 14 15))
user> (take 1 (floyd-2))
;;=> ((1))
How about this:
(defn floyd []
(map (fn[n]
(let [start (/ (* n (inc n)) 2)]
(range (inc start) (+ start n 2))))
(iterate inc 0)))
(take 4 (floyd))

How to move first list item to the end?

For given list:
(1 2 3 4)
I'd like to get as output:
(2 3 4 1)
Code I came up with looks like this:
(flatten (cons (rest l) (list (first l))))
However my feeling is, that I overcomplicated this. Any other ideas?
You don't need to flatten a cons, just use concat.
Here is an example:
(let [fruit ["apple" "orange" "grapes" "bananas"]]
(concat (rest fruit) [(first fruit)])
Developing #stonemetal's hint, we can quickly and lazily rotate a vector thus:
(defn rotate [v n]
(let [cv (count v), n (mod n cv)]
(concat (subvec v n cv) (subvec v 0 n))))
It works in either direction:
(map #(rotate (vec (range 5)) %) (range -2 8))
;((3 4 0 1 2)
; (4 0 1 2 3)
; (0 1 2 3 4)
; (1 2 3 4 0)
; (2 3 4 0 1)
; (3 4 0 1 2)
; ...
; (2 3 4 0 1))
So to rotate the first in a sequence to the end:
(rotate (vec (range 1 5)) 1)
You can also use destructuring (either on the function arguments or in a let binding).
(let [[h & tail] '(1 2 3 4)]
(concat tail (list h))) ;=> (1 2 3 4)