Related
I need to draw an n sample from the uniform distribution on the interval [a,b] such that no two numbers are closer than d > 0. I can draw a sample and check this property and then throw it away and try again if not, but if n is large relative to b-a that could take a looong time. Is there a simple and nice algorithm to solve this problem? The numbers got to be uniformly distributed on [a,b], no deterministic setup.
This problem is equivalent to choosing n numbers greater than or equal to d and whose sum is equal to b - a.
There will be some solution provided that n * d <= b - a. We can write a recursive algorithm that looks for one:
b - a - X < (n - 1) * D
X > b - a - (n - 1) * d
FindSpacedSample(n, d, a, b)
1. if n * d > b - a then return "no solution"
2. avail = [d, b - a - (n - 1) * d]
3. guess = random(avail)
4. print(guess)
5. FindSpacedSample(n - 1, d, a + guess, b)
Example: n = 5, a = 0, b = 10, d = 1, assuming real numbers
FindSpacedSample(5, 1, 0, 10)
5 * 1 >? b - a? no
avail = [1, 10 - 0 - 4 * 1] = [1, 6]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(4, 1, 2, 10)
4 * 1 >? 10 - 2? no
avail = [1, 10 - 2 - 3 * 1] = [1, 5]
guess = random(avail) = 4 (for the sake of argument)
print(4)
FindSpacedSample(3, 1, 6, 10)
3 * 1 >? 10 - 6? no
avail = [1, 10 - 6 - 2 * 1] = [1, 2]
guess = random(avail) = 1 (for the sake of argument)
print(1)
FindSpacedSample(2, 1, 7, 10)
2 * 1 >? 10 - 7? no
avail = [1, 10 - 7 - 1 * 1] = [1, 2]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(1, 1, 9, 10)
1 * 1 >? 10 - 9? no
avail = [1, 10 - 9 - 0 * 1] = [1, 1]
guess = 1
print(1)
We should also have stopping condition n = 0. Then we get the sequence of spaces 2, 4, 1, 2, 1; we see these sum to ten; and we can get the values as follows:
point1 = 2 = 2
point2 = 2 + 4 = 6
point3 = 2 + 4 + 1 = 7
point4 = 2 + 4 + 1 + 2 = 9
point5 = 2 + 4 + 1 + 2 + 1 = 10
Now, there are a couple of ways in which this result is less than totally uniform:
the first number will never be less than d
earlier numbers tend to be spaced further apart
We can fix these by:
shuffling the spacings before converting to points
subtracting from each point some random value from [0, point1 - a].
So, if we shuffled 2, 4, 1, 2, 1 to 4, 1, 1, 2, 2 we'd get points 4, 5, 6, 8, 10; and if we subtracted 3 from each one (taken randomly between 0 and 4) we'd get 1, 2, 3, 5, 7.
Does this give you a uniform distribution over the set of all possible solutions? I'd be surprised if it did, but I'd also be surprised if what this does give you differs from that truly uniform distribution to an appreciable degree.
I am trying to learn a little bit about Wolfram Mathematica.
I want to define a symbolic function
where x is a vector, g is a function that takes a vector and returns a vector and h is a function that takes a vector and returns a scalar.
I don't want to commit to specific g and h, I just want to have a symbolic representation for them.
I would like to get a symbolic form for the third order derivatives (which would be a tensor) -- is there a way to do that in Wolfram Mathematica?
EDIT: I should mention, A and C are matrices, and b and d are vectors.
Here is what I tried and didn't work:
Try this
f[x_] := x*E^x
and then this
f'[x]
returns this
E^x + E^x x
and this
f''[x]
returns this
2 E^x + E^x x
Three methods of notation, all producing the same result.
f[x_] := Sin[x] + x^2
D[f[x], x]
2 x + Cos[x]
f'[x]
2 x + Cos[x]
f''[x]
2 - Sin[x]
using an alternative form of definition of f
Clear[f]
f = Sin[x] + x^2
D[f, x]
2 x + Cos[x]
δx f
2 x + Cos[x]
δ{x,2} f
2 - Sin[x]
Note
δ{x,2} f is supposed to be the subscript form of D[f, {x, 2}] but web formatting is limited.
Scoping out matrix and vector dimensions, and using S instead of C since the latter is a protected (uppercase) symbol.
A = {{1, 2, 3}, {4, 5, 6}};
x = {2, 4, 8};
A.x
{34, 76}
b = {3, 5};
h = 3;
h (A.x + b)
{111, 243}
S = {{1, 2}, {3, 4}, {5, 6}};
S.(h (A.x + b))
{597, 1305, 2013}
d = {2, 4, 8};
g = 2;
g (S.(h (A.x + b)) + d)
{1198, 2618, 4042}
So compatible matrix and vector assumptions can be made. (It turns out the derivative result comes out the same without taking the trouble to make the assumptions.)
Clear[A, x, b, S, d]
$Assumptions = {
Element[A, Matrices[{m, n}]],
Element[x, Vectors[n]],
Element[b, Vectors[m]],
Element[S, Matrices[{n, m}]],
Element[d, Vectors[n]]};
f = g (S.(h (A.x + b)) + d);
D[f, x]
g S.(h A.1)
D[f, {x, 3}]
0
I'm not sure if these results are correct so if you find out do comment.
In the past I've often used loops of the following kind (Haskell example):
upperBoundToTuples :: Int -> [(Int, Int)]
upperBoundToTuples n = [(x,y) | x <- [0..n], y <- [x+1..n]]
The above code produces tuples of range (0,1)..(n,n) where for all x < y.
I was wondering if it there was an efficient way of getting those (x,y) indices given a single index? Possible applications include optimization problems on the GPU where loops are not allowed and each thread only gets an index.
Also if it is possible for the 2D case, could such an algorithm be generalized to multiple dimensions?
You're asking for a bijection from [0, N(N+1)/2) to pairs (x, y) with 0 <= x < y <= N.
Here's one simple way to define it (in pseudocode, but should be trivial to convert to Haskell):
x0, y0 = i / (N + 1), i % (N + 1)
if x0 < y0 then result = (x0, y0)
else result = (N - 1 - x0, N - y0)
Here's a visualisation of the function for N=6. The map is laid out in a table with rows of length N+1=7, with the first row representing the value of the function for i=0 to 6, the next i=7 to 13 and so on. If you look very closely and carefully, you can see that things above the leading diagonal map to their own location in the table, and things on or below the diagonal map rotationally to the later entries.
5,6 0,1 0,2 0,3 0,4 0,5 0,6
4,6 4,5 1,2 1,3 1,4 1,5 1,6
3,6 3,5 3,4 2,3 2,4 2,5 2,6
And here's the opposite of this visualisation: a table T of size (N+1) by (N+1) with T[x, y] = i where i is mapped to (x, y) by the function above.
- 1 2 3 4 5 6
- - 9 10 11 12 13
- - - 17 18 19 20
- - - - 16 15 14
- - - - - 8 7
- - - - - - 0
- - - - - - -
Higher dimensions
This method can probably be made to work in higher dimensions, but I don't immediately see how. As an alternative, here's a simple but somewhat inefficient method that does work in arbitrary dimensions.
First, note there's choose(N + 1, k) increasing sequences of length k from the numbers from 0 to N (where choose(N, k) is the binomial coefficient). Of those, choose(N, k - 1) of them end with N. That gives this recursive function that generates the sequences in descending colexicographical order (again in pseudocode):
sequence(N, k, index)
= [] if k == 0
= sequence(N - 1, k - 1, index) + [N] if index < choose(N, k - 1)
= sequence(N - 1, k, index - choose(N, k - 1)) otherwise
Here's, sequence(5, 3, index) for index between 0 and 19:
0 -> [3, 4, 5]
1 -> [2, 4, 5]
2 -> [1, 4, 5]
3 -> [0, 4, 5]
4 -> [2, 3, 5]
5 -> [1, 3, 5]
6 -> [0, 3, 5]
7 -> [1, 2, 5]
8 -> [0, 2, 5]
9 -> [0, 1, 5]
10 -> [2, 3, 4]
11 -> [1, 3, 4]
12 -> [0, 3, 4]
13 -> [1, 2, 4]
14 -> [0, 2, 4]
15 -> [0, 1, 4]
16 -> [1, 2, 3]
17 -> [0, 2, 3]
18 -> [0, 1, 3]
19 -> [0, 1, 2]
We may equivalently consider [(x,y) | x<-[0..n], y<-[0..x-1]]. This list has length
ℓn = x=0∑n x
= n·(n+1)/2.
Hence we can get, to a given ℓ, the nearest lower n through
2·ℓn = n·(n+1) = n2 + n
n~ = -½ ± √(¼ + 2·ℓn)
In particular, for a given index i,
ni− = ⌊-½ ± √(¼ + 2·i)⌋
is the x-length of the last fully completed triangle. Thus, the index i lies in the row ni−+1. That triangle had an area of
ℓni− = ni−·(ni−+1)/2
which we therefore need to subtract from i to get the remainder index (in y-direction). This gives rise to the definition
lowerTriangularTuple :: Int -> (Int,Int)
lowerTriangularTuple i = (nmin+1, i - (nmin*(nmin+1))`div`2)
where nmin = floor $ -1/2 + sqrt(1/4 + 2 * fromIntegral i)
Example:
GHCi> lowerTriangularTuple <$> [0..30]
[(1,0),(2,0),(2,1),(3,0),(3,1),(3,2),(4,0),(4,1),(4,2),(4,3),(5,0),(5,1),(5,2),(5,3),(5,4),(6,0),(6,1),(6,2),(6,3),(6,4),(6,5),(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(8,0),(8,1),(8,2)]
I can not get my head around why mathematica can not solve this equation:
In[22]:= Solve[1/x^12 - 2/x^6 + 1/2 (-2 + x)^2 HeavisideTheta[-2 + x] == 0]
During evaluation of In[22]:= Solve::nsmet: This system cannot be solved with the methods available to Solve. >>
Out[22]= Solve[1/x^12 - 2/x^6 + 1/2 (-2 + x)^2 HeavisideTheta[-2 + x] == 0]
using mathematica 9.0.1.0.
Edit:
In[24]:= Plot[1/x^12 - 2/x^6 + 1/2 (-2 + x)^2 HeavisideTheta[-2 + x], {x, 1, 3}]
FindRoot is often more aggressive
FindRoot[1/x^12-2/x^6+1/2(-2+x)^2 HeavisideTheta[-2+x]==0, {x, 3}]
and that almost instantly returns the solution.
If you want to look for analytic solutions ( which is what Solve does ),
assume the step function has a value 0 or 1 , use Solve and check the step function assumption against the results:
Select[ Solve[1/x^12 - 2/x^6 + 1/2 (-2 + x)^2 (0) == 0] ,
HeavisideTheta[-2 + x /. #] == 0 & ]
{{x -> -(1/2^(1/6))}, {x -> 1/2^(1/6)}}
Select[ Solve[1/x^12 - 2/x^6 + 1/2 (-2 + x)^2 (1) == 0] ,
HeavisideTheta[-2 + x /. #] == 1 & ]
{{x -> Root[2 - 4 #1^6 + 4 #1^12 - 4 #1^13 + #1^14 &, 2]}}
Of the three solutions, the one I guess you want is the last one , the root of a 14th order polynomial, which you need to eval numerically anyway:
N[Root[2 - 4 #1^6 + 4 #1^12 - 4 #1^13 + #1^14 &, 2] ]
2.18999
I need to create a 3 by 3 real orthonormal symbolic matrix in Mathematica.
How can I do so?
Not that I recommend this, but...
m = Array[a, {3, 3}];
{q, r} = QRDecomposition[m];
q2 = Simplify[q /. Conjugate -> Identity]
So q2 is a symbolic orthogonal matrix (assuming we work over reals).
You seem to want some SO(3) group parametrization in Mathematica I think. You will only have 3 independent symbols (variables), since you have 6 constraints from mutual orthogonality of vectors and the norms equal to 1. One way is to construct independent rotations around the 3 axes, and multiply those matrices. Here is the (perhaps too complex) code to do that:
makeOrthogonalMatrix[p_Symbol, q_Symbol, t_Symbol] :=
Module[{permute, matrixGeneratingFunctions},
permute = Function[perm, Permute[Transpose[Permute[#, perm]], perm] &];
matrixGeneratingFunctions =
Function /# FoldList[
permute[#2][#1] &,
{{Cos[#], 0, Sin[#]}, {0, 1, 0}, {-Sin[#], 0, Cos[#]}},
{{2, 1, 3}, {3, 2, 1}}];
#1.#2.#3 & ## MapThread[Compose, {matrixGeneratingFunctions, {p, q, t}}]];
Here is how this works:
In[62]:= makeOrthogonalMatrix[x,y,z]
Out[62]=
{{Cos[x] Cos[z]+Sin[x] Sin[y] Sin[z],Cos[z] Sin[x] Sin[y]-Cos[x] Sin[z],Cos[y] Sin[x]},
{Cos[y] Sin[z],Cos[y] Cos[z],-Sin[y]},
{-Cos[z] Sin[x]+Cos[x] Sin[y] Sin[z],Cos[x] Cos[z] Sin[y]+Sin[x] Sin[z],Cos[x] Cos[y]}}
You can check that the matrix is orthonormal, by using Simplify over the various column (or row) dot products.
I have found a "direct" way to impose special orthogonality.
See below.
(*DEFINITION OF ORTHOGONALITY AND SELF ADJUNCTNESS CONDITIONS:*)
MinorMatrix[m_List?MatrixQ] := Map[Reverse, Minors[m], {0, 1}]
CofactorMatrix[m_List?MatrixQ] := MapIndexed[#1 (-1)^(Plus ## #2) &, MinorMatrix[m], {2}]
UpperTriangle[ m_List?MatrixQ] := {m[[1, 1 ;; 3]], {0, m[[2, 2]], m[[2, 3]]}, {0, 0, m[[3, 3]]}};
FlatUpperTriangle[m_List?MatrixQ] := Flatten[{m[[1, 1 ;; 3]], m[[2, 2 ;; 3]], m[[3, 3]]}];
Orthogonalityconditions[m_List?MatrixQ] := Thread[FlatUpperTriangle[m.Transpose[m]] == FlatUpperTriangle[IdentityMatrix[3]]];
Selfadjunctconditions[m_List?MatrixQ] := Thread[FlatUpperTriangle[CofactorMatrix[m]] == FlatUpperTriangle[Transpose[m]]];
SO3conditions[m_List?MatrixQ] := Flatten[{Selfadjunctconditions[m], Orthogonalityconditions[m]}];
(*Building of an SO(3) matrix*)
mat = Table[Subscript[m, i, j], {i, 3}, {j, 3}];
$Assumptions = SO3conditions[mat]
Then
Simplify[Det[mat]]
gives 1;...and
MatrixForm[Simplify[mat.Transpose[mat]]
gives the identity matrix;
...finally
MatrixForm[Simplify[CofactorMatrix[mat] - Transpose[mat]]]
gives a Zero matrix.
========================================================================
This is what I was looking for when I asked my question!
However, let me know your thought on this method.
Marcellus
Marcellus, you have to use some parametrization of SO(3), since your general matrix has to reflect the RP3 topology of the group. No single parametrization will cover the whole group without either multivaluedness or singular points. Wikipedia has a nice page about the various charts on SO(3).
Maybe one of the conceptually simplest is the exponential map from the Lie algebra so(3).
Define an antisymmetric, real A (which spans so(3))
A = {{0, a, -c},
{-a, 0, b},
{c, -b, 0}};
Then MatrixExp[A] is an element of SO(3).
We can check that this is so, using
Transpose[MatrixExp[A]].MatrixExp[A] == IdentityMatrix[3] // Simplify
If we write t^2 = a^2 + b^2 + c^2, we can simplify the matrix exponential down to
{{ b^2 + (a^2 + c^2) Cos[t] , b c (1 - Cos[t]) + a t Sin[t], a b (1 - Cos[t]) - c t Sin[t]},
{b c (1 - Cos[t]) - a t Sin[t], c^2 + (a^2 + b^2) Cos[t] , a c (1 - Cos[t]) + b t Sin[t]},
{a b (1 - Cos[t]) + c t Sin[t], a c (1 - Cos[t]) - b t Sin[t], a^2 + (b^2 + c^2) Cos[t]}} / t^2
Note that this is basically the same parametrization as RotationMatrix gives.
Compare with the output from
RotationMatrix[s, {b, c, a}] // ComplexExpand // Simplify[#, Trig -> False] &;
% /. a^2 + b^2 + c^2 -> 1
Although I really like the idea of Marcellus' answer to his own question, it's not completely correct. Unfortunately, the conditions he arrives at also result in
Simplify[Transpose[mat] - mat]
evaluating to a zero matrix! This is clearly not right. Here's an approach that's both correct and more direct:
OrthogonalityConditions[m_List?MatrixQ] := Thread[Flatten[m.Transpose[m]] == Flatten[IdentityMatrix[3]]];
SO3Conditions[m_List?MatrixQ] := Flatten[{OrthogonalityConditions[m], Det[m] == 1}];
i.e. multiplying a rotation matrix by its transpose results in the identity matrix, and the determinant of a rotation matrix is 1.