2

I'm having trouble creating a random vector V in Matlab subject to the following set of constraints: (given parameters N,D, L, and theta)

  1. The vector V must be N units long
  2. The elements must have an average of theta
  3. No 2 successive elements may differ by more than +/-10
  4. D == sum(L*cosd(V-theta))

I'm having the most problems with the last one. Any ideas?

Edit
Solutions in other languages or equation form are equally acceptable. Matlab is just a convenient prototyping tool for me, but the final algorithm will be in java.

Edit
From the comments and initial answers I want to add some clarifications and initial thoughts.

I am not seeking a 'truly random' solution from any standard distribution. I want a pseudo randomly generated sequence of values that satisfy the constraints given a parameter set.

The system I'm trying to approximate is a chain of N links of link length L where the end of the chain is D away from the other end in the direction of theta.

My initial insight here is that theta can be removed from consideration until the end, since (2) in essence adds theta to every element of a 0 mean vector V (shifting the mean to theta) and (4) simply removes that mean again. So, if you can find a solution for theta=0, the problem is solved for all theta.

As requested, here is a reasonable range of parameters (not hard constraints, but typical values):
5<N<200
3<D<150
L==1
0 < theta < 360

CodeFusionMobile
  • 14,812
  • 25
  • 102
  • 140
  • 1
    What is `L`, and how does `D` relate to the distribution? The first three are as simple as `rand(N, 1)*10 + theta` but you haven't said how you want `D` or `L` to relate, nor if you want a uniform distribution as above etc etc. This is not a well formed question, you need to think a lot more about it. – Dan Apr 10 '13 at 06:13
  • @Dan: rand(N,1)*10+theta does not satisfy 2 – carlosdc Apr 10 '13 at 06:19
  • @carlosdc you are right my bad. This does though: `(rand(N, 1) - 0.5)*10 + theta`. And if you actually want a mean of theta rather than an expected value of theta (which I doubt) then try `V = rand(N,1); V = (V - mean(V))*10 + theta` – Dan Apr 10 '13 at 06:26
  • Incidentally this also satisfies constraint 4, for example I just choose `L` to equal `0`, then `D` also equals `0` etc since they are unlinked to anything else but each other you can just choose either `D` or `L` at will as the question stands – Dan Apr 10 '13 at 06:28
  • @Dan: I agree that the question is somewhat lacking precision. Here's how I understand it: The user chooses any arbitrary D, L, N and theta, the code needs to generate an N dimensional vector that satisfies 1-4. – carlosdc Apr 10 '13 at 06:32
  • Lastly `E[V -theta] == 0` by constraint 2, I could be wrong but because of that and since `cos` is symmetrical about the y-axis, intuitively I would assume that would make `E[cos(V - theta)] == cos(E[V - theta])` which is `1`. Which finally makes `D == N*L` ? Hence @carlosdc I don't think you can satisfy any arbitrary `D` and `L` combination. I guess if it's not a uniform distribution then maybe. I think you need to ask this on a stats forum and come up with a better description of the distribution before you'll have any luck trying to code it. – Dan Apr 10 '13 at 06:35
  • 3
    What is the type of random data you want (integers, doubles, ...)? Also, should the numbers be drawn from a uniform distribution, or a Gaussian, Boltzmann, F, student-t, ...? Also, what is the *range* of values to be used? I mean: what is the maximum/minimum value for the random number? is that the entire integer range? – Rody Oldenhuis Apr 10 '13 at 06:35
  • @Dan I do actually want a hard mean constraint rather than just an expected value. – CodeFusionMobile Apr 10 '13 at 12:06
  • @Rody Oldenhuis I have laid out my only strict constraint requirements given the supplied parameters and want a way to autogenerate a vector that satisfies the constraints in some pseudo-random way. How you accomplish the task is completely up to you. The question is intentionally vague on those questions to give you the freedom to be creative. – CodeFusionMobile Apr 10 '13 at 12:06
  • @CodeFusionMobile: when you say in matlab cos(alpha) that means cosine of alpha expressed in radians. So this is going to really sound like nitpicking, but I'm really not: could you please update either the valid parameter ranges to radians or the restrictions to convert from degrees to radians? – carlosdc Apr 10 '13 at 16:02
  • @carlosdc Corrected in OP, should be cosd – CodeFusionMobile Apr 10 '13 at 20:18

4 Answers4

1

I would start by creating a "valid" vector. That should be possible - say calculate it for every entry to have the same value.

Once you got that vector I would apply some transformations to "shuffle" it. "Rejection sampling" is the keyword - if the shuffle would violate one of your rules you just don't do it.

As transformations I come up with:

  • switch two entries
  • modify the value of one entry and modify a second one to keep the 4th condition (Theoretically you could just shuffle two till the condition is fulfilled - but the chance that happens is quite low)

But maybe you can find some more.

Do this reasonable often and you get a "valid" random vector. Theoretically you should be able to get all valid vectors - practically you could try to construct several "start" vectors so it won't take that long.

bdecaf
  • 4,652
  • 23
  • 44
0

You don't give us a lot of detail to work with, so I'll assume the following:

  • random numbers are to be drawn from [-127+theta +127-theta]
  • all random numbers will be drawn from a uniform distribution
  • all random numbers will be of type int8

Then, for the first 3 requirements, you can use this:

N = 1e4;
theta = 40;
diffVal = 10;

g = @() randi([intmin('int8')+theta  intmax('int8')-theta], 'int8') + theta;
V = [g(); zeros(N-1,1, 'int8')];
for ii = 2:N
    V(ii) = g();
    while abs(V(ii)-V(ii-1)) >= diffVal
        V(ii) = g();
    end
end

inline the anonymous function for more speed.

Now, the last requirement,

D == sum(L*cos(V-theta))

is a bit of a strange one...cos(V-theta) is a specific way to re-scale the data to the [-1 +1] interval, which the multiplication with L will then scale to [-L +L]. On first sight, you'd expect the sum to average out to 0.

However, the expected value of cos(x) when x is a random variable from a uniform distribution in [0 2*pi] is 2/pi (see here for example). Ignoring for the moment the fact that our limits are different from [0 2*pi], the expected value of sum(L*cos(V-theta)) would simply reduce to the constant value of 2*N*L/pi.

How you can force this to equal some other constant D is beyond me...can you perhaps elaborate on that a bit more?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
  • Note that the elements of V don't need to be drawn from a distribution like the uniform distribution. Forcing (4) would indeed be difficult in this case. What is needed is a pseudo-randomly generated vector that satisfies the constraints. – CodeFusionMobile Apr 10 '13 at 12:25
  • @CodeFusionMobile: Random numbers ***always*** come from some distribution....And I understood that you need "a pseudo-randomly generated vector that satisfies the constraints", but what is not clear to me is the details of those constraints. – Rody Oldenhuis Apr 10 '13 at 13:02
0

Here's a way of doing it. It is clear that not all combinations of theta, N, L and D are valid. It is also clear that you're trying to simulate random objects that are quite complex. You will probably have a hard time showing anything useful with respect to these vectors.

The series you're trying to simulate seems similar to the Wiener process. So I started with that, you can start with anything that is random yet reasonable. I then use that as a starting point for an optimization that tries to satisfy 2,3 and 4. The closer your initial value to a valid vector (satisfying all your conditions) the better the convergence.

function series = generate_series(D, L, N,theta)
s(1) = theta;
for i=2:N,
    s(i) = s(i-1) + randn(1,1);
end
f = @(x)objective(x,D,L,N,theta)
q = optimset('Display','iter','TolFun',1e-10,'MaxFunEvals',Inf,'MaxIter',Inf)
[sf,val] = fminunc(f,s,q);
val
series = sf;



function value= objective(s,D,L,N,theta)
a = abs(mean(s)-theta);
b = abs(D-sum(L*cos(s-theta)));
c = 0;
for i=2:N,
    u =abs(s(i)-s(i-1)) ;
    if u>10,
        c = c + u;
    end
end
value = a^2 + b^2+ c^2;

It seems like you're trying to simulate something very complex/strange (a path of a given curvature?), see questions by other commenters. Still you will have to use your domain knowledge to connect D and L with a reasonable mu and sigma for the Wiener to act as initialization.

carlosdc
  • 12,022
  • 4
  • 45
  • 62
  • I had never heard of Wiener processes, and looks very interesting. I think you may be overthinking the problem though. See my updates to OP – CodeFusionMobile Apr 10 '13 at 12:38
  • I have a working simulation for the forward kinematics that verifies my constraints are valid (with some range treatment for the angle values), it's the inverse problem that is difficult to solve since the system is under constrained and there are infinite solutions for most of the valid parameter space (but unique for certain parameter sets). – CodeFusionMobile Apr 10 '13 at 13:11
0

So based on your new requirements, it seems like what you're actually looking for is an ordered list of random angles, with a maximum change in angle of 10 degrees (which I first convert to radians), such that the distance and direction from start to end and link length and number of links are specified?

Simulate an initial guess. It will not hold with the D and theta constraints (i.e. specified D and specified theta)

angles = zeros(N, 1)

for link = 2:N
    angles (link) = theta(link - 1) + (rand() - 0.5)*(10*pi/180)
end

Use genetic algorithm (or another optimization) to adjust the angles based on the following cost function:

dx = sum(L*cos(angle));
dy = sum(L*sin(angle));

D = sqrt(dx^2 + dy^2);
theta = atan2(dy/dx);

the cost is now just the difference between the vector given by my D and theta above and the vector given by the specified D and theta (i.e. the inputs).

You will still have to enforce the max change of 10 degrees rule, perhaps that should just make the cost function enormous if it is violated? Perhaps there is a cleaner way to specify sequence constraints in optimization algorithms (I don't know how).

I feel like if you can find the right optimization with the right parameters this should be able to simulate your problem.

Dan
  • 45,079
  • 17
  • 88
  • 157
  • But I'm trying to find a set of values V that match the parameters supplied, not find a random set of thetas and simulate the chain calculating D. That's a straightforward forward-kinematic problem that I've already solved. What I'm asking for is a way to find an inverse solution. – CodeFusionMobile Apr 10 '13 at 12:29
  • OK, I see what you're saying – Dan Apr 10 '13 at 12:31
  • Well it wont be efficient, but you could put the above in a loop and keep trying until you hit a sequence of thetas that satisfy your constraint 4 as a start. You also might start with a chain of random theta and then think of a clever way to tweak them iteratively until it satisfies your contraints using the difference vector from one end to the other as a kind of goal to seek. Genetic Algorithms might be good for this. – Dan Apr 10 '13 at 12:41
  • I've thought about that, but ultimately I'm going to be running some optimization like that on the solution space for the constraints optimizing for other parameters outside this sub-problem. It would be nice if I could ensure feasibility for all solutions – CodeFusionMobile Apr 10 '13 at 12:46
  • 1
    The more I think about it, the more I think GA is the way to go here. But perhaps you should ask this on a forum where there are more experts on stochastic processes as that's effectively what you're asking someone to design in this question. – Dan Apr 10 '13 at 12:50
  • Updated amswer with an outline of how I would proceed using this approach – Dan Apr 10 '13 at 13:28