Shuffling a list in Mathematica - wolfram-mathematica

What's the best/easiest way to shuffle a long list in Mathematica?

RandomSample[list]
Yes, it's really that simple. At least since version 6.
Before RandomSample was introduced, one might use:
#[[ Ordering[Random[] & /# #] ]] & # list

Before RandomSample was introduced, I've used the below MathGroup-function heavily, though RandomSample is faster at least by one magnitude on my machine.
In[128]:= n = 10;
set = Range#n
Out[129]= {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
In[130]:= Take[set[[Ordering[RandomReal[] & /# Range#n]]], n]
Out[130]= {8, 4, 5, 2, 3, 10, 7, 9, 6, 1}
Other problem besides performance is that if the same random reals are hit twice (improbable, though possible) Ordering will not give these two in random order.

Currently I use
list[[PermutationList#RandomPermutation#Length[list]]]
This is for Mathematica 8. Combinatorica also has a RandomPermutation function (earlier versions).
I am looking for other/better solutions, if there are any.

Related

How do I apply Map[] to a function using two arguments in Mathematica?

In general, I was trying to compute the norm of the difference between every set two elements in a list which looks something like
X = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}}
therefore evaluating
Norm[X[[1]]-X[[2]]]
Norm[X[[1]]-X[[3]]]
Norm[X[[2]]-X[[3]]]
Now, applying Outer[] is one possible way how to do this
Outer[Norm[X[[#1]] - X[[#2]]] &, {1,2,3}, {1,2,3}]
but unfortunately it results in a quite slow code if I increase the number of elements in X and the length of each element.
Is there any possible way to construct a Map[] operation? Something like
MapThread[Norm[X[[#1]] - X[[#2]]] &,{{1,2,3},{1,2,3}}]
does not work give the desired "currying" which I was looking for.
I'm using Mathematica Version 11.2.0.0, so I don't have access to Curry[].
Would be happy about any advice!
mX = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}
Apply[Norm#*Subtract, #] & /# Subsets[mX, {2}]
Two equivalent approaches:
(Norm#*Subtract) ### Subsets[mX, {2}]
Apply[Norm#*Subtract, Subsets[mX, {2}], {1}]

Is there a range function to create a list of numbers?

I'm looking to make a consecutive list of numbers in Applescript. One could create such a list using a repeat loop, but that seems messy. Is there anything that works like this?
range from 1 to 10
-> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Yes, answering the last question first, there is (using four more lines) a list-of-lists repeat loop:
set nlist to {}
repeat with n from 0 to 9
set nlist2 to {n + 1}
set nlist to nlist & nlist2
end repeat
nlist
--> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Basically, if you repeatedly merge lists, you create a list of lists,
whereas...
set nlist to {}
repeat with n from 0 to 9
set nlist to {n + 1}
end repeat
nlist
--> {10}
...would just result in the last number of the loop.
(Surely, there must be other ways, too.)
The closest one-line equivalent of ranges is probably "items 1 through 10" -but only for an existing list; example:
set rangeB to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
set nlist to items 1 thru 10 of rangeB
nlist
-->{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Regarding the title question, if it's a function you need, in Applescript they are called handlers, there is no preset range function, but you may create a customized range function for your task like this:
on range(a, b)
set nlist to {}
repeat with n from a - 1 to b - 1
set nlist2 to {n + 1}
set nlist to nlist & nlist2
end repeat
end range
--
range(5, 20)
-->{5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
And I think the real question behind the question (which I just recently had myself) was: "I'm coming from the world of spreadsheets, where are the ranges, where are the functions in AppleScript?" And the answer to that is: Ranges are now really lists, or items of a list, functions are handlers which you need write once, it's a bit extra work at first, but the upside is how easy then -and helpful- it can be to add customized functions, a whole new range (correction: list) of possibilities. And the AppleScript repeat loops are what the copy/paste down was in spreadsheets, essentially saying, in comparison: here is a function, I'd like to apply this to list A and it gets me list B with results, and repeat it again, from here to there. (Or non-stop.) Yes, copy/paste-down seems easier at first, and repeat with its "repeat with i" looks a bit esoteric at first, I agree, but on further consideration it is actually pretty straightforward, and there is really no way around it in so many coding situations. It's a core engine! "Eat, sleep, rave, repeat!" ;D And the repeat loops can be upgraded, again: offering more practical possibilities than the spreadsheet way of copy/paste-down.
No, there is not.
AppleScript is a very simple scripting language with a small core command set.
But it's extendible. Feel free to write a scripting addition or library providing this functionality.
PS: In AppleScript repeat loops are not messy at all ;-)

How do I add a random offset to values in a Pseq?

Given a Pseq similar to the following:
Pseq([1, 2, 3, 4, 5, 6, 7, 8], inf)
How would I randomise the values slightly each time? That is, not just randomly alter the 8 values once at initialisation time, but have a random offset added each time a value is sent to the stream?
Here's a neat way:
(Pseq([1, 2, 3, 4, 5, 6, 7, 8], inf) + Pgauss(0, 0.1))
First you need to know that Pgauss is just a pattern that generates gaussian random numbers. You can use any other kind of pattern such as Pwhite.
Then you need to know the really pleasant bit: performing basic math operations on Patterns (as above) composes the patterns (by wrapping them in Pbinop).

How to find modulus patterns using Mathematica

Is there any way to find the lowest modulus of a list of integers? I'm not sure how to say it correctly, so I'm going to clarify with an example.
I'd like to input a list (mod x) and output the "same" list, modulus y (< x). For example, the list {0, 4, 6, 10, 12, 16, 18, 22} (mod 24) is essentially the same as {0, 4} (mod 6).
Thank you for all your help.
You are looking for a set of arithmetic sequences. We'll consider your example
ee = {0, 4, 6, 10, 12, 16, 18, 22};
which has two such sequences, and an example with four of them.
ff = {0, 3, 7, 11, 17, 20, 24, 28, 34, 37, 41, 45};
In this second one we start with {0,3,7,11} and then increase by 17. So what is the general way to get from the nth term to the n+1th? If the set has k sequences (k=2 for ee and 4 for ff) then add the modulus to the n-k+1th term. What is the modulus? It is the difference between the nth and n-kth terms.
Putting this together and assuming we know k (we don't in general, but we'll get to that) we have a recurrence of the form f(n+1)=f(n-k+1) + (f(n)-f(n-k)). So we need to find a recurrence (if one exists), check that it is of the correct form, and post-process if so.
Here is code to do all this. Note that it in effect solves for k.
findArithmeticSequences[ll : {_Integer ..}] := With[
{rec = FindLinearRecurrence[ll]},
{Take[ll, Length[rec] - 1], ll[[Length[rec]]]} /;
ListQ[rec] &&
(rec === {1, 1, -1} || MatchQ[rec, {1, 0 .., 1, -1}])
]
(Afficionados of pure functions might prefer the variant below. Failure cases are handled a bit differently, for no compelling reason.)
findArithmeticSequences2[ll : {_Integer ..}] :=
If[ListQ[#] &&
(# === {1, 1, -1} || MatchQ[#, {1, 0 .., 1, -1}]), {Take[ll,
Length[#] - 1], ll[[Length[#]]]}, $Failed] &[
FindLinearRecurrence[ll]]
Tests:
In[115]:= findArithmeticSequences[ee]
Out[115]= {{0, 4}, 6}
In[116]:= findArithmeticSequences[ff]
Out[116]= {{0, 3, 7, 11}, 17}
Note that one can "almost" do such problems by polynomial factorization (if the input has no partial sequences at the end). For example, the polynomial
In[117]:= poly = Plus ## (x^ee)
Out[117]= 1 + x^4 + x^6 + x^10 + x^12 + x^16 + x^18 + x^22
factors into
(1+x^4)*(1+x^6+x^12+x^18)
which contains the needed information in a way that is easy to see. Unfortunately for this particular purpose, Factor will factor beyond this point, and obscure the information in so doing.
I keep wondering if there might be a signal processing way to go about this sort of thing, e.g. via DFTs. But I've not come up with anything.
Daniel Lichtblau
Wow, thank you Daniel for this! It works nearly the way I want it to. Your method is just a bit "too restrictive". It doesn't return anything useful if 'FindLinearRecurrence' doesn't find any recurrence. I've modified your method a bit, so it suits my needs better. I hope you don't mind. Here's my code.
findArithmeticSequences[ll_List] := Module[{rec = FindLinearRecurrence[ll]},
If[! MatchQ[rec, {1, 0 ..., 1, -1}], Return[ll],
Return[{ll[[Length[rec]]], Take[ll, Length[rec] - 1]}];
];
];
I had a feeling it'd have to involve recurrence, I just don't have enough experience with Mathematica to implement it. Thank you again for your time!
Mod is listable, and you can remove duplicate elements by DeleteDuplicates. So
DeleteDuplicates[Mod[{0, 4, 6, 10, 12, 16, 18, 22}, 6]]
(*
-> {0,4}
*)

How to get the oddly indexed elements in a list in mathematica

How to get the oddly indexed elements in a list? I am thinking of Select, but did not find anything returning an element's position, especially considering there are repetitive elements in the list.
Also in general, how to select those elements whose indices satisfy some certain conditions?
Here's a few more in addition to #belisarius's answer, which don't require computing Length[lis]:
Take[lis, {1, -1, 2}]
lis[[1 ;; -1 ;; 2]]
You can often use -1 to represent the "last" position.
There are a lot of ways, here are some of them:
In[2]:= a = Range[10];le = Length#a;
In[3]:= Table[a[[i]], {i, 1, le, 2}]
In[5]:= Pick[a, Table[Mod[i, 2], {i, 1, le}], 1]
In[6]:= a[[1 ;; le ;; 2]]
In general, with Pick[] (as an example) you can model any conceivable index mask.
For some reason the terse form of Span has been omitted from the answers.
Range[20][[;;;;2]]
{1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
Quoting the documentation:
;;;;k
from the beginning to the end in steps of k.

Resources