ocaml vector space - vector

I have a R3 space and I'm trying to figure some math "problems" with OCAML functions.
Define function "move", which moves plane based on the plane_name (ex. plane1) and vector (x, y, z):
example:
plane1 = [(1,2,-3); (10,5,2); (-2,3,7)]
move plane1 (1,2,-3);;
- : (int * int * int) list = [(2, 4, -6); (11, 7, -1); (-1, 5, 4)]
Thank you

I'll restrict my answer to problem 3.
I don't know where you're at with OCaml and what limitations have been imposed on your answer. (Forgive me, but I'm assuming this is a homework problem.) Let's assume the point of the exercise is to begin to think recursively. So then you want to write a function like this:
let move plane (x, y, z) = (( code goes here ))
For thinking recursively, the basic insight is that a plane is a list of points and you want to do the same thing to all the points. So a lower-level view of the function would be like this:
let rec move point_list (x, y, z) = (( code goes here ))
Now, a list is either empty, or it isn't. You just need to figure out what to do in each case. Furthermore, when the list is not empty you can use your own function recursively as long as you call it with a smaller list.
If, in fact, the point of this exercise is not to learn recursive thinking, then the answer would be completely different. In particular, there's a function in the List module that would make it pretty easy to solve the problem.
Update
Apparently you want to solve the problem non-recursively. To show how this would work, here is a function that takes two points and adds 1 to the x, y, and z coordinates of both points:
let add1 [(x1, y1, z1); (x2, y2, z2)] =
[(x1 + 1, y1 + 1, z1 + 1); (x2 + 1, y2 + 1, z2 + 1)]
This will cause a compiler warning because it fails for many possible inputs. In particular, it fails whenever the list has some number of points other than 2. To eliminate the warning, we need to decide what we want to return for those cases. Let's say we always return the list unchanged in those cases. Then we get the following:
let add1 = function
| [(x1, y1, z1); (x2, y2, z2)] ->
[(x1 + 1, y1 + 1, z1 + 1); (x2 + 1, y2 + 1, z2 + 1)]
| pts -> pts
I guess you know what you want, but this is not particularly idiomatic OCaml.
Another way to solve the problems non-recursively (without rec) would be to use functions from the List module. That would be much more idiomatic, and in fact is probably what I would do in a real-world situation.

Related

Understanding Forward.Diff issues

I got an apparently quite common Julia error when trying to use AD with forward.diff. The error messages vary a bit (sometimes matching function name sometimes Float64)
MethodError: no method matching logL_multinom(::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(logL_multinom), Real}, Real, 7}})
My goal: Transform a probability vector to be unbounded (θ -> y), do some stuff (namely HMC sampling) and transform back to the simplex space whenever the unnormalized posterior (logL_multinom()) is evaluated. DA should be used to overome problems for later, more complex, models than this.
Unfortunately, neither the Julia documentation, not the solutions from other questions helped me figure the particular problem out. Especially, it seems to work when I do the first transformation (y -> z) outside of the function, but the first transformation is a 1-to-1 mapping via logistic and should not cause any harm to differentiation.
Here is an MWE:
using LinearAlgebra
using ForwardDiff
using Base
function logL_multinom(y)
# transform to constrained
K = length(y)+1
k = collect(1:(K-1))
# inverse logit:
z = 1 ./ (1 .+ exp.(-y .- log.(K .- k))) # if this is outside, it works
θ = zeros(eltype(y),K) ; x_cumsum = zeros(eltype(y),K-1)
typeof(θ)
for i in k
x_cumsum[i] = 1-sum(θ)
θ[i] = (x_cumsum[i]) * z[i]
end
θ[K] = x_cumsum[K-1] - θ[K-1]
#log_dens_correction = sum( log(z*(1-z)*x_cumsum) )
dot(colSums, log.(θ))
end
colSums = [835, 52, 1634, 3469, 3053, 2507, 2279, 1115]
y0 = [-0.8904013824298864, -0.8196709647741431, -0.2676845405543302, 0.31688184351556026, -0.870860684394019,0.15187821053559714,0.39888119498547964]
logL_multinom(y0)
∇L = y -> ForwardDiff.gradient(logL_multinom,y)
∇L(y0)
Thanks a lot and especially some further readings/ explanations for the problem are appreciated since I'll be working with it moreoften :D
Edit: I tried to convert the input and any intermediate variable into Real / arrays of these, but nothing helped so far.

Line of Intersection between 2 Planes

I watched and tried to understand bunch of sites and videos about this, and I came into a weird conclusions and some questions. I need some help to explain which one of the method is right, or even both of them are right (but I got different result from each methods).
I'm sorry that I'm bad at explaining things, the first method is solve the equations normally. But, here the link for the video I tried to learn from
https://www.youtube.com/watch?v=o7CfCDkRwfY
Second method is to do cross product for the direction and find the point by set one of the variables as 0. https://www.youtube.com/watch?v=jozabh0lFmo
I tried for this example
x+2y+z−1=0
2x+3y−2z+2=0
and turned out for different answers. Is both of the method are correct, or which one? Thank you.
You have two equations with three unknowns.
You can eliminate one variable and solve for a relationship between the remaining two. Let's eliminate z.
Multiply the first equation by 2:
2x + 4y + 2z = 2
Add this to the second equation:
4x + 7y = 0
You can solve for y as a function of x:
y = -4x/7
Substitute this back into the first equation:
x - 8x/7 + z = 1
Simplify by combining the first and second terms:
-x/7 + z = 1
Solve for z:
z = 1 + x/7
Now you have an equation for the line in 3D space.
-inf <= x <= +inf
y = -4x/7
z = 1 + x/7
Both your equations are satisfied by these two points. Since two points are enough to define a line in Euclidean space I'd say I've got the correct answer.
This line goes through the point (0, 0, 1). It also goes through (7, -4, 2)
Here's a parametric representation of that line for -inf <= t <= +inf:
(x, y, z) = (0, 0, 1) + t*(7, -4, 1)
You can see that when t = 0 (x, y, z) = (0, 0, 1) (first point above) and when t = 1 (x, y, z) = (7, -4, 2) (second point above).
I didn't look at either of your videos. This is how I'd solve it.
This is high school algebra.

Prolog recursively multiply

I'm trying to multiply two numbers in Prolog recursively i.e. 3*4 = 3+3+3+3 = 12.
My code is :
mult(0,Y,Y).
mult(X,Y,Z) :-
NewX is X-1,
Z is Y + mult(NewX,Y,Z).
but I keep either in an infinite loop or being told mult is not a function.
What you here constructed is a predicate. A predicate is not the same as a function in computer science, you can not write A is B + some_pred(C), or at least not as far as I know in ISO Prolog, and definitely not without adding some extra logic.
In order to pass values, one uses variables. We can thus call the mult/3 predicate recursively, and use a variable that will be unified with the result. We can then perform arithmetic with it, like:
mult(0, _, 0).
mult(X, Y, Z) :-
X1 is X - 1,
mult(X1, Y, Z1),
Z is Y + Z1.
Note that you can not reassign a (different) value to a variable. So if, like you did in the question, use Z twice, then given Y is not 0, this will fail.
The above is however still not sufficient, since it will produce a result, but then get stuck in an infinite loop since if it calls (eventually) mult(0, 4, Z) (4 is here just a value), there are two ways to resolve this: with the base case, and with the recursive case.
We thus need a "guard" for the second case, like:
mult(0, _, 0).
mult(X, Y, Z) :-
X > 0,
X1 is X - 1,
mult(X1, Y, Z1),
Z is Y + Z1.
We then obtain for example:
?- mult(14, 25, Z).
Z = 350 ;
false.
One can improve the speed of this mult/3 predicate by implementing a version with an accumulator. I leave this as an exercise.

recursive traversal through a graph, counting ways to a point

Got a graph which is looks like this one:
I want to count all possible ways to a specific point p(i,j) from p(0,0) in this graph. I think i can do it with Depth-first search. How i should extend the Depth-first search, so its don't count some ways twice?
The best way is to count the number of ways without actually following all of the paths. Let F(x, y) be the number of ways to get to your destination point. Then, you can see that in your graph, F(x, y) = F (x+1, y) + F (x, y+1) + F(x+1, y+1). You want F(0,0). Your base cases are going to be F(i, j) = 1 (one way to get there if you're already there: don't go anywhere) and F(any number > i, any j) and F(i, any number > j) = 0 because there's no way to get to your destination point once you've passed it.
Update with more detail: Now how to evaluate this formula? You could do it recursively, but a naive implementation will be extremely inefficient. A naive implementation would just be something like this in pseudocode that loosely looks like python:
i = ...
j = ...
def paths (x, y):
if (x > i) or (y > j):
return 0
if (x == i) and (y == j):
return 1
else:
return paths (x+1, y) + paths (x, y+1) + paths (x+1, y+1)
print F(0, 0)
The problem with this is that if you start at (0,0), your first level of recursive calls will be (0, 1), (1, 0), and (1, 1). When these calls in turn evaluate, (0, 1) will compute (0, 2) (1, 1), and (1, 2); then (1, 0) will compute (1, 1), (2, 0), and (2, 1), and then (1, 1) will compute (1, 2), (2, 1), and (2, 2). Notice how many of these calls are redundant in that they compute the same value. The technique to resolve this is to keep a matrix that memorizes the values of F. So then the code might look something like this:
i = ...
j = ...
memorizedValues = ... #make an i by j grid filled with -1
memorizedValues[i][j] = 1 #initial condition
def paths (x, y):
if (x > i) or (y > j):
return 0
if (memorizedValues[x][y] != -1): #check for a memorized value before
return memorizedValues[x][y] # starting more recursion!
else:
memorizedValues[x][y] = paths (x+1, y) + paths (x, y+1) + paths (x+1, y+1)
return memorizedValues[x][y]
print F(0, 0)
This is still not the most efficient implementation, but I think it gets the point across. It's considerably faster than counting each path by following it and backtracking!
You can use BFS and either mark the nodes or use a map to keep track of them. However, if your graph is large, BFS entails keeping it all in memory. DFS is better at it. However, DFS can get lost in a large graph unless you put a depth restriction on it.
Anyhow, to speed up your program you might consider stopping early if:
the graph is disconnected
you reach a bridge
Other heuristics:
visit a neighbour of degree 1 first before going any further.
I wrote a somewhat similar program to see how far I can optimize it:
https://github.com/eamocanu/allPathsFinder

Simple MATLAB/Octave simulation

This should be a very simple question for anyone who has some experience in this area, but I'm still new to this.
I have the following system (or here is an image with better resolution):
alt text http://img199.imageshack.us/img199/2140/equation1.png
Given the following input:
u = min(2 - t/7.5, 2*(mod(t, 2) < 1));
I need to plot the output of system y.
I am describing the system with the following function:
function xprime = func(t, x)
u = min(2 - t/7.5, 2*(mod(t, 2) < 1));
xprime = [
x(2);
x(3);
0.45*u - 4*x(3)^2 - x(2)*x(1) - 4*x(2) - 2*x(1);
x(5);
sin(t) - 3*x(5)*x(1);
];
and simulating with ode23, like this:
[tout, xout] = ode23(#func, [0 15], [1.5; 3; -0.5; 0; -1])
After the simulation, xout will have five columns. My question is: how do I know which one is the output of the y system?
EDIT: Ok, so to put it simple, I'd like to plot the solution like this:
a = 1 % what goes here? 1, 2, 3, 4 or 5?
plot(tout, xout(:,a))
The one that corresponds to y, which appears to be x(1), of course.
If you compare your code to the equations, you can see that x(1) appears in the code every place that y appears in the equations. That would be my best guess.
[T,Y,TE,YE,IE] = ode23(odefun,tspan,y0,options)
The following table lists the output arguments for the solvers.
T Column vector of time points.
Y Solution array. Each row in Y corresponds to the solution at a time returned in the corresponding row of T.
TE The time at which an event occurs.
YE The solution at the time of the event.
IE The index i of the event function that vanishes.
Isten fizesse!

Resources