While previously attempting to ascertain the dimensions of a matrix, I have used the core.matrix function shape. This function has done exactly what I have asked. I input one nested vector into the function and output the dimension. However, I am looking to input multiple matrices/nested vectors into the function and am running into trouble. Is the shape function capable of handling multiple inputs, or is there another way to determine the dimensions of multiple nested vectors?
An example input would look like: [[1 1] [1 1]] [[2 2 2] [2 2 2]]
the expected output would be: [2 2] for first matrix and [3 3] for second matrix, as both inputs are square matrices.
This sounds a bit like mapping shape over the slices of a matrix.
If you write your input as [[[1 1] [1 1]] [[2 2 2] [2 2 2]]] then call (slices 0 ...) on that it would give you the sequence of matrices that you can then feed to the map function. Or you can skip the slices part and just (map shape list-of-matrices).
Related
I have collection of lists and I want to apply "reduce +" for each list in collection. I think I should combine "apply", "map" and "reduce +", but I can't understand how.
Example:
[[1 2 3] [4 5 3] [2 5 1]] => [6 12 8]
No need for apply. map and reduce will work fine:
(map (partial reduce +) [[1 2 3] [4 5 3] [2 5 1]])
map will call the function on each member of the list and partial simply creates a 'curried' version of reduce that expects one parameter. it could also be written like #(reduce + %) or (fn [lst] (reduce + lst))
Update
You could actually use apply in place of reduce here as well (just not both):
(map (partial apply +) [[1 2 3] [4 5 3] [2 5 1]])
Further Update
If you have any performance concerns, see the comments on this answer for some great tips by #AlexMiller
Just starting out with core.logic, version "0.8.11":
(q/run* [q]
(q/fresh [a]
(q/membero a [2 3]))
(q/membero q [1]))
I don't understand the result: (1 1).
My understanding is that I create another variable a with fresh, which can take a value of 2 or 3.
And q can take a value of 1. Therefore I was expecting to see something like: (1), or (1 2 1 3), or maybe ([1 2] [1 3]) or even ({:q 1 :a 2} {:q 1 :a 3}), but not the actual result.
Another example:
(q/run* [q]
(q/fresh [a]
(q/membero a [1 2 3])
(q/membero q [3 4 5])
(q/== a q)))
;; make sense to me, returns (3)
(q/run* [q]
(q/fresh [a]
(q/membero a [1 2 3]))
(q/membero q [3 4 5]))
;; does not make sense to me, returns (3 4 3 5 4 3 5 4 5)
;; I was expecting `(3 4 5)`
Could someone explain what is happening here?
core.logic can be viewed a search algorithm, searching for possible ways to assign values to all the relevant variables that don't cause a conflict. It has a lot of very smart pruning techniques so that it doesn't search subtrees that are known to be no good, but basically it is a search.
It found two ways to assign variables that satisfy your query:
a=2, q=1
a=3, q=1
So it is returning two results. But you only ask about q (that's what the argument to run* is, the set of variables you want to know the values of), and q is the same in both of those assignments, so you see the same result (1) twice. You should not in general assume that results from run* will be distinct, unless you have gone to some effort to make them so.
Likewise in your last example, there are three values you could assign to q, and each of them works for any of the three values you could assign to a, so you get 3*3=9 results, with each q value repeated three times. The order these results are returned in is (from your perspective) arbitrary; really they are ordered in a way that helps core.logic prevent getting deadlocked in other, more complicated programs. You could see all the a,q pairs if you wanted, by writing instead (q/run* [a q] ...).
Let's say I have a data structure like so:
[[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]]
And what I want to end up with is:
[[1 2 3] [4 5 6] [7 8 9] [10 11 12]]
Is there any function that does this automatically?
Basically I'm converting/transforming a SQL result set to CSV, and there are some rows that will transform to 2 rows in the CSV. So my map function in the normal case returns a vector, but sometimes returns a vector of vectors. Clojure.data.csv needs a list of vectors only, so I need to flatten out the rows that got pivoted.
Mapcat is useful for mapping where each element can expand into 0 or more output elements, like this:
(mapcat #(if (vector? (first %)) % [%]) data)
Though I'm not sure if (vector? (first %)) is a sufficient test for your data.
A different approach using tree-seq:
(def a [[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]])
(filter (comp not vector? first)
(tree-seq (comp vector? first) seq a))
I am stretching to use tree-seq here. Would someone with more experience care to comment on if there is a better way to return only the children other than using what is effectively a filter of (not branch?)
Clojure: Semi-Flattening a nested Sequence answers your question, but I don't want to mark this question as a duplicate of that one, since you're really asking a different question than he was; I wonder if it's possible to move his answer over here.
I'm new to Clojure and trying to learn the basics. One thing that tripped me up is understanding the correlation between the data structures and the functions they use.
For instance, if I create a new Vector:
(def my-vec [1 2 3])
Then when I try to call my-vec:
(my-vec)
I get:
ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:437)
I know that I can pass an argument and it appears to be calling get but how do I know? What args does PersistentVector take and where do I find documentation about it?
I tried:
(doc PersistentVector)
But that returns nil.
Documentation can be found under IPersistentVector here:
http://clojure.org/data_structures
In particular:
Vectors implement IFn, for invoke() of one argument, which they presume is an index and look up in themselves as if by nth, i.e. vectors are functions of their indices.
If you pass a number to a Clojure vector the vector will use that number as an index into it's self and return the value at that index:
user> (def my-vec [1 2 3 4 5])
#'user/my-vec
user> (my-vec 2)
3
this allows you to write expressions like this which grab several keys out of a vec
user> (map my-vec [1 3 4])
(2 4 5)
You can think of a vector as mapping indexes 0, 1, 2, ..., N to values, one at each index. Abstractly, it's a special case of a map where the keys are integers starting from 0. That notion helps to see the consistency in Clojure between maps and vectors when used as functions:
(<ILookup-able-collection> <key-for-lookup>)
JavaScript does something similar, allowing you to use [] syntax for lookup on arrays or objects.
my-vec isn't a function, so you should call: my-vec not (my-vec)
Try: (nth my-vec i) for get i-th element of this vector.
link: nth
Is there a 'proper' way to iterate over a two-dimensional sequence in Clojure?
Suppose I had a list of lists of numbers, like this
((1 2 3)
(4 5 6)
(7 8 9))
and I wanted to generate a new list of lists with each number incremented by one. Is there an easy way to do this in Clojure without relying on nested maps or loop/recurs? I've been able to do it, but my solutions are ugly and I find them difficult to understand when I re-read them.
Thanks
What you describe is precisely what clojure.walk is for:
(def matrix [[1 2 3]
[4 5 6]
[7 8 9]])
(use 'clojure.walk :only [prewalk])
(prewalk #(if (number? %) (inc %) %) matrix)
=> [[2 3 4] [5 6 7] [8 9 10]]
Note 1: it is idiomatic to use vectors instead of parentheses for literal sequential collections.
Note 2: walk preserves type.
You can always just use a list comprehension. I find myself using them quite often coming from an imperative background so I don't know how idiomatic it is. In your specific case, you can do:
(for [my-list my-matrix] (map inc my-list))
For the two-dimensional case, you could do something like:
(map #(map inc %) my-two-d-list)
That's not too bad to read: apply the function #(map inc %) to each element in a list.
For the higher-order case, you're basically talking about tree-traversal. You'd want a function that takes in a tree and a function, and applies that function to each node in the tree. You can find functions for this in clojure.walk.
The other answers by Sean and Matt both show concise and effective ways of getting the right result.
However there are some important extensions you can make to this:
It would be nice to handle the case of higher dimensions
It is good to wrap the functionality in a higher order function
Example code:
;; general higher order function
(defn map-dimensions [n f coll]
(if (= n 1)
(map f coll)
(map #(map-dimensions (dec n) f %) coll)))
;; use partial application to specialise to 2 dimensions
(def map-2d (partial map-dimensions 2))
(map-2d inc
'((1 2 3)
(4 5 6)
(7 8 9)))
=> ((2 3 4) (5 6 7) (8 9 10))
Since the introduction of core.matrix in 2013, this is now a much better way of handling operations over multi-dimensional arrays:
(use 'clojure.core.matrix)
(def M [[1 2 3]
[4 5 6]
[7 8 9]])
(emap inc M)
=> [[2 3 4 ]
[5 6 7 ]
[8 9 10]]
Advantages of using core.matrix:
Clean, idiomatic Clojure code
Lots of general purpose n-dimensional array manipulation functions - transpose, shape, reshape, slice, subarray etc.
Ability to plug in high performance array implementations (e.g. for big numerical arrays)
A belated answer, and maybe not exactly what is needed: you could try flatten. It will return a seq that you can iterate over:
(flatten '((1 2 3)
(4 5 6)
(7 8 9)))
user=> (1 2 3 4 5 6 7 8 9)
And in order to increment matrix elements and reassemble the matrix:
(partition 3 (map inc (flatten '((1 2 3)
(4 5 6)
(7 8 9)))))