Is there a Mathematica function like inject in Ruby? For example, if I want the product of the elements in a list, in Ruby I can write:
list.inject(1) { |prod,el| prod * el }
I found I can just use Product in Mathematica:
Apply[Product, list]
However, this isn't general enough for me (like, if I don't just want the product or sum of the numbers). What's the closest equivalent to inject?
The equivalent is Fold.
I think this is more typically called "reduce" -- that's the Python name anyway.
Translating your example:
Fold[#1*#2&, 1, list]
That #1*#2& is a binary lambda function that multiplies its arguments.
In this case you could just use Times instead:
Fold[Times, 1, list]
Or of course just apply Times to the list:
Apply[Times, list]
Or, for short:
Times ## list
NOTE: The version in your question where you use Product instead of Times will not work.
Product is for something else, namely the analog of Sum.
Related
Suppose I want to write a dynamic function that gets an object subtype of AbstractMatrix and shuffles the values along a specified dimension. Surely there can be various approaches and ways to do this, but suppose the following way:
import Random.shuffle
function shuffle(data::AbstractMatrix; dims=1)
n = size(data, dims)
shuffled_idx = shuffle(1:n)
data[shuffled_idx, :] #This line is wrong. It's not dynamic
A wrong way is to use several (actually indefinite) if-else statements like if dims==1 do... if dims==2 do. But it isn't the way to do these kinds of things. I could write data::AbstractArray then the input could have various dimensions. So this came to my mind that this can be possible if I can do something like getindex(data, [idxs]; dims). But I checked for the dims keyword argument (or even positional one) in the dispatches of getindex, but there isn't such a definition. So how can I get values by specified indexes and along a dim?
You are looking for selectdim:
help?> selectdim
search: selectdim
selectdim(A, d::Integer, i)
Return a view of all the data of A where the index for dimension d equals i.
Equivalent to view(A,:,:,...,i,:,:,...) where i is in position d.
Here's a code example:
function myshuffle(data::AbstractMatrix; dim=1)
inds = shuffle(axes(data, dim))
return selectdim(data, dim, inds)
end
Make sure not to use 1:n as indices for AbstractArrays, as they may have non-standard indices. Use axes instead.
BTW, selectdim apparently returns a view, so you may or may not need to use collect on it.
I want to count the frequencies of all elements in a given Vec, e.g. something like
count_frequencies(vec![1,1,1,4,1,2,3,5,4])
should return the following Vec:
[(1,4), (2,1), (3,1), (4,2), (5,1)]
(the order does not matter). While I know how I could implement such a function, it seems to me like there should already be an existing implementation in some crate. After some googling, I only found a crate named frequency, but didn't find any example in the documentation.
So, my question is: is there a crate that can achieve this task and, if so, how can I use it?
Edit: If you as well know a function which goes in the other direction, I would also be interested in that :)
Itertools offers counts, but you'd have to convert the result (a HashMap) into a Vec yourself.
Alternatively, sort the vector (costs O(n log n), but may - in practice - be faster than a HashMap-based approach) and use dedup_with_count on the sorted vector.
It isn't really needed because it is one-liner anyway:
let frequencies = v
.iter()
.copied()
.fold(HashMap::new(), |mut map, val|{
map.entry(val)
.and_modify(|frq|*frq+=1)
.or_insert(1);
map
});
There are different requirements for different tasks so there is no need to make some standard method for this.
I want to write a version that accepts a supplementary argument. The difference with the initial version only resides in a few lines of codes, potentially within loops. A typical example is to user a vector of weight w.
One solution is to completely rewrite a new function
function f(Vector::a)
...
for x in a
...
s += x[i]
...
end
...
end
function f(a::Vector, w::Vector)
...
for x in a
...
s += x[i] * w[i]
...
end
...
end
This solution duplicates code and therefore makes the program harder to maintain.
I could split ... into different helper functions, which are called by both functions, but the resulting code would be hard to follow
Another solution is to write only one function and use a ? : structure for each line that should be changed
function f(a, w::Union(Nothing, Vector) = nothing)
....
for x in a
...
s += (w == nothing)? x[i] : x[i] * w[i]
...
end
....
end
This code requires to check a condition at every step in a loop, which does not sound efficient, compared to the first version.
I'm sure there is a better solution, maybe using macros. What would be a good way to deal with this?
There are lots of ways to do this sort of thing, ranging from optional arguments to custom types to metaprogramming with #eval'ed code generation (this would splice in the changes for each new method as you loop over a list of possibilities).
I think in this case I'd use a combination of the approaches suggested by #ColinTBowers and #GnimucKey.
It's fairly simple to define a custom array type that is all ones:
immutable Ones{N} <: AbstractArray{Int,N}
dims::NTuple{N, Int}
end
Base.size(O::Ones) = O.dims
Base.getindex(O::Ones, I::Int...) = (checkbounds(O, I...); 1)
I've chosen to use an Int as the element type since it tends to promote well. Now all you need is to be a bit more flexible in your argument list and you're good to go:
function f(a::Vector, w::AbstractVector=Ones(size(a))
…
This should have a lower overhead than either of the other proposed solutions; getindex should inline nicely as a bounds check and the number 1, there's no type instability, and you don't need to rewrite your algorithm. If you're sure that all your accesses are in-bounds, you could even remove the bounds checking as an additional optimization. Or on a recent 0.4, you could define and use Base.unsafe_getindex(O::Ones, I::Int...) = 1 (that won't quite work on 0.3 since it's not guaranteed to be defined for all AbstractArrays).
In this case, using Optional Arguments may play the trick.
Just make the w argument default to ones().
I've come up against this problem a few times. If you want to avoid the conditional if statement inside the loop, one possibility is to use multiple dispatch over some dummy types. For example:
abstract MyFuncTypes
type FuncWithNoWeight <: MyFuncTypes; end
evaluate(x::Vector, i::Int, ::FuncWithNoWeight) = x[i]
type FuncWithWeight{T} <: MyFuncTypes
w::Vector{T}
end
evaluate(x::Vector, i::Int, wT::FuncWithWeight) = x[i] * wT.w[i]
function f(a, w::MyFuncTypes=FuncWithNoWeight())
....
for x in a
...
s += evaluate(x, i, w)
...
end
....
end
I extend the evaluate method over FuncWithNoWeight and FuncWithWeight in order to get the appropriate behaviour. I also nest these types within an abstract type MyFuncTypes, which is the second input to f (with default value of FuncWithNoWeight). From here, multiple dispatch and Julia's type system takes care of the rest.
One neat thing about this approach is that if you decide later on you want to add a third type of behaviour inside the loop (not necessarily even weighting, pretty much any type of transformation will be possible), it is as simple as defining a new type, nesting it under MyFuncTypes, and extending the evaluate method to the new type.
UPDATE: As Matt B. has pointed out, the first version of my answer accidentally introduced type instability into the function with my solution. As a general rule I typically find that if Matt posts something it is worth paying close attention (hint, hint, check out his answer). I'm still learning a lot about Julia (and am answering questions on StackOverflow to facilitate that learning). I've updated my answer to remove the type instability pointed out by Matt.
Cyclomatic complexity measures how many possible branches can be taken through a function. Is there an existing function/tool to calculate it for R functions? If not, suggestions are appreciated for the best way to write one.
A cheap start towards this would be to count up all the occurences of if, ifelse or switch within your function. To get a real answer though, you need to understand when branches start and end, which is much harder. Maybe some R parsing tools would get us started?
You can use codetools::walkCode to walk the code tree. Unfortunately codetools' documentation is pretty sparse. Here's an explanation and sample to get you started.
walkCode takes an expression and a code walker. A code walker is a list that you create, that must contain three callback functions: handler, call, and leaf. (You can use the helper function makeCodeWalker to provide sensible default implementations of each.) walkCode walks over the code tree and makes calls into the code walker as it goes.
call(e, w) is called when a compound expression is encountered. e is the expression and w is the code walker itself. The default implementation simply recurses into the expression's child nodes (for (ee in as.list(e)) if (!missing(ee)) walkCode(ee, w)).
leaf(e, w) is called when a leaf node in the tree is encountered. Again, e is the leaf node expression and w is the code walker. The default implementation is simply print(e).
handler(v, w) is called for each compound expression and can be used to easily provide an alternative behavior to call for certain types of expressions. v is the character string representation of the parent of the compound expression (a little hard to explain--but basically <- if it's an assignment expression, { if it's the start of a block, if if it's an if-statement, etc.). If the handler returns NULL then call is invoked as usual; if you return a function instead, that's what's called instead of the function.
Here's an extremely simplistic example that counts occurrences of if and ifelse of a function. Hopefully this can at least get you started!
library(codetools)
countBranches <- function(func) {
count <- 0
walkCode(body(func),
makeCodeWalker(
handler=function(v, w) {
if (v == 'if' || v == 'ifelse')
count <<- count + 1
NULL # allow normal recursion
},
leaf=function(e, w) NULL))
count
}
Also, I just found a new package called cyclocomp (released 2016). Check it out!
Original question:
I know Mathematica has a built in map(f, x), but what does this function look like? I know you need to look at every element in the list.
Any help or suggestions?
Edit (by Jefromi, pieced together from Mike's comments):
I am working on a program what needs to move through a list like the Map, but I am not allowed to use it. I'm not allowed to use Table either; I need to move through the list without help of another function. I'm working on a recursive version, I have an empty list one down, but moving through a list with items in it is not working out. Here is my first case: newMap[#, {}] = {} (the map of an empty list is just an empty list)
I posted a recursive solution but then decided to delete it, since from the comments this sounds like a homework problem, and I'm normally a teach-to-fish person.
You're on the way to a recursive solution with your definition newMap[f_, {}] := {}.
Mathematica's pattern-matching is your friend. Consider how you might implement the definition for newMap[f_, {e_}], and from there, newMap[f_, {e_, rest___}].
One last hint: once you can define that last function, you don't actually need the case for {e_}.
UPDATE:
Based on your comments, maybe this example will help you see how to apply an arbitrary function:
func[a_, b_] := a[b]
In[4]:= func[Abs, x]
Out[4]= Abs[x]
SOLUTION
Since the OP caught a fish, so to speak, (congrats!) here are two recursive solutions, to satisfy the curiosity of any onlookers. This first one is probably what I would consider "idiomatic" Mathematica:
map1[f_, {}] := {}
map1[f_, {e_, rest___}] := {f[e], Sequence##map1[f,{rest}]}
Here is the approach that does not leverage pattern matching quite as much, which is basically what the OP ended up with:
map2[f_, {}] := {}
map2[f_, lis_] := {f[First[lis]], Sequence##map2[f, Rest[lis]]}
The {f[e], Sequence##map[f,{rest}]} part can be expressed in a variety of equivalent ways, for example:
Prepend[map[f, {rest}], f[e]]
Join[{f[e]}, map[f, {rest}] (#Mike used this method)
Flatten[{{f[e]}, map[f, {rest}]}, 1]
I'll leave it to the reader to think of any more, and to ponder the performance implications of most of those =)
Finally, for fun, here's a procedural version, even though writing it made me a little nauseous: ;-)
map3[f_, lis_] :=
(* copy lis since it is read-only *)
Module[{ret = lis, i},
For[i = 1, i <= Length[lis], i++,
ret[[i]] = f[lis[[i]]]
];
ret
]
To answer the question you posed in the comments, the first argument in Map is a function that accepts a single argument. This can be a pure function, or the name of a function that already only accepts a single argument like
In[1]:=f[x_]:= x + 2
Map[f, {1,2,3}]
Out[1]:={3,4,5}
As to how to replace Map with a recursive function of your own devising ... Following Jefromi's example, I'm not going to give to much away, as this is homework. But, you'll obviously need some way of operating on a piece of the list while keeping the rest of the list intact for the recursive part of you map function. As he said, Part is a good starting place, but I'd look at some of the other functions it references and see if they are more useful, like First and Rest. Also, I can see where Flatten would be useful. Finally, you'll need a way to end the recursion, so learning how to constrain patterns may be useful. Incidentally, this can be done in one or two lines depending on if you create a second definition for your map (the easier way), or not.
Hint: Now that you have your end condition, you need to answer three questions:
how do I extract a single element from my list,
how do I reference the remaining elements of the list, and
how do I put it back together?
It helps to think of a single step in the process, and what do you need to accomplish in that step.