CrossProduct and DotProduct - Expand these equations - triangulation

I'm trying to use a formulae from http://www.blackpawn.com/texts/pointinpoly/default.html the upper of the two options. (I have already used the lower).
I just can not seem to wrap my head around the CrossProduct(b-a, p1-a) etc. Could someone Please expand these for me. They are below.
function SameSide(p1,p2, a,b)
cp1 = CrossProduct(b-a, p1-a)
cp2 = CrossProduct(b-a, p2-a)
if DotProduct(cp1, cp2) >= 0 then return true
else return false
as I understand it they should come out to this.
## Using the following as p=x,z, a=x,z, b=x,z, c=x,z
## p=4,1 a=2,0 b=4,3 c=0,4
function SameSide(px, pz, ax, az, bx, bz, cx, cz){
cp1x=(cx-bx*px-bx)
cp1z=(cz-bz*pz-bz)
cp2x=(cx-bx*ax-bx)
cp2z=(cz-bz*az-bz)
DotProd=(cp1x*cp2x+cp1z*cp2z)
}
But when trying this in Excel I get wrong answers again.
Please help! 8-|

Your DotProduct computation is correct. However, the cross product of 2 vectors v and w is :
cpx = vy*wz - vz*wy
cpy = vz*wx - vx*wz
cpz = vx*wy - vy*wx
where in your case, vx = bx-ax vy = by-ay and vz=bz-az, and wx=p1x-ax (or respectively p2x-ax) and similarly for y and z.

Related

Can you please tell me how to solve four transcendental equations of four unknowns?

I have tried solving 4 equations of 4 unknowns in MATLAB and Mathematica.
I used vpasolve for finding the unknowns in MATLAB. Here is the MATLAB code.
Y1 = 0.02;
l1 = 0.0172;
syms Y2 Y3 l2 l3;
lambda = [0.0713 0.0688 0.0665];
b1 = 0.1170;
b3 = 0.1252;
t2_1 = (2*pi/lambda(1))*l2;
t3_1 = (2*pi/lambda(1))*l3;
t2_3 = (2*pi/lambda(3))*l2;
t3_3 = (2*pi/lambda(3))*l3;
t1_1 = (2*pi/lambda(1))*l1;
t1_3 = (2*pi/lambda(3))*l1;
eq1 = 2*Y1*tan(t1_1)+Y2*tan(t2_1)+Y3*tan(t3_1)==0;
eq2 = 2*Y1*tan(t1_3)+Y2*tan(t2_3)+Y3*tan(t3_3)==0;
eq3 = b1== (t1_1*Y1)+(t2_1*(Y2/2)*((sec(t2_1)^2)/(sec(t1_1)^2)))+(t3_1*(Y3/2)*((sec(t3_1)^2)/(sec(t1_1)^2)));
eq4 = b3== (t1_3*Y1)+(t2_3*(Y2/2)*((sec(t2_3)^2)/(sec(t1_3)^2)))+(t3_3*(Y3/2)*((sec(t3_3)^2)/(sec(t1_3)^2)));
E=[eq1 eq2 eq3 eq4];
S=vpasolve(E,[Y2,Y3,l2,l3]);
For the same equations, I wrote the below code in Mathematica.
eqns = {2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1 + t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2) + t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1 + t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2) + t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};
NMinimize[Norm[Map[First, eqns]], {Y2,Y3,l2,l3}]
But both are giving me different solutions and those are not the required solutions. I suppose I should use some other function for solving the equations. Can anyone help me finding out how to solve these equations? Your help is highly appreciated. Thank you.
EDIT
If I use the below code for finding the roots, I'm able to find the solutions but I just want positive roots. I tried the code which you have mentioned for getting positive roots but its not working for this and I don't know why. Can you please check this once?
Y1=0.0125;l1=0.010563;lambda={0.0426,0.0401,0.0403,0.0423,0.0413}; b1 = 0.0804;
b3 = 0.0258;
t2_1 = (2*Pi/lambda[[1]])*l2;
t3_1 = (2*Pi/lambda[[1]])*l3;
t2_3 = (2*Pi/lambda[[5]])*l2;
t3_3 = (2*Pi/lambda[[5]])*l3;
t1_1 = (2*Pi/lambda[[1]])*l1;
t1_3 = (2*Pi/lambda[[5]])*l1;
eqns = {2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1 + t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2) + t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1 + t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2) + t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};
Try
Y1=0.02;l1=0.0172;lambda={0.0713,0.0688,0.0665};b1=0.1170;b3=0.1252;
t21=(2*Pi/lambda[[1]])*l2;t31=(2*Pi/lambda[[1]])*l3;t23=(2*Pi/lambda[[3]])*l2;
t33=(2*Pi/lambda[[3]])*l3;t11=(2*Pi/lambda[[1]])*l1;t13=(2*Pi/lambda[[3]])*l1;
eqns={2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1+t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2)+t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1+t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2)+t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};
tbl=Table[
{y2i,y3i,l2i,l3i}=RandomReal[{0,.2},4];
Quiet[root=Check[FindRoot[eqns,{{Y2,y2i,0,.2},{Y3,y3i,0,.2},{l2,l2i,0,.2},{l3,l3i,0,.2}}],False]];
If[root===False,Nothing,root]
,{256}];
roots=Sort[Map[{Y2,Y3,l2,l3}/.#&,tbl],Norm[#1]<Norm[#2]&]
If[roots=={},"It found no roots in that range using those coefficients",
Map[First,eqns]/.{Y2->roots[[1,1]],Y3->roots[[1,2]],l2->roots[[1,3]],l3->roots[[1,4]]}]
That will look for roots starting at 256 different random locations greater than, but near 0. The way I have written FindRoot this time it will stop if the search is outside the range 0,.2 You can change that range if needed.
Next your functions have many local minima that trap FindRoot. So it should discard all local minima found inside that range.
And I have hidden the warning messages, usually not a good idea to do.
Then it will Sort the roots to show those nearest 0 first.
If you want it to sort to show the results nearest some given value then I can modify the Sort to show those first, I just need to know where you want the roots nearest to.
And finally it substitutes the Y2,Y3,l2,l3 of the smallest root it found back into the four equations to demonstrate that the results are very very near zero and this is a real root instead of a local minima.
After trying that a few times I found one root at {0.0203704,0.0225972,0.0163842,0.0181147} and that looks very close to your required values if I swap Y2 and Y3 and swap l2 and l3. Is that perhaps the root that you are looking for?
If you need more then please tell me exactly what is needed.
Please check ALL this VERY carefully to make certain I have made no mistakes.

Differentiation consistency in matlab

I'm trying to write a program in matlab that checks how consistent the definition of the derivative becomes:
(f(x+h)-f(x))/h ~= f'(x)
when h is small enough. Thus far i have this:
function [errList] = diffConsistency(f,df,x,iMax,h0)
h=h0;
for i=1:iMax
leftSide = (f(x+h) - f(x)) / h;
rightSide = df(x);
errList = abs(leftSide - rightSide);
h = h*10^(-1);
end
I then use f=#(x)sin(x) and df=#(x)cosx, I'm new to using function handles so this might be wrong completely. iMax is set to 10 and h0 = 1, x=rand(10)
Could anyone check if this is even remotely correct. Especially the use of the function handles inside the diffConsistency function and use of the rand.
Should i define x differently, leftside rightside are correct? etc
Any feedback would help.
Thanks in advance
You use some specific data that obscures the result. You input 10x10 random numbers, and output a 10x10 matrix of errors, but this is only for the last i, as you overwrite errList every iteration!
change the function to:
function [errList] = diffConsistency(f,df,x,iMax,h0)
h=h0;
for i=1:iMax
leftSide = (f(x+h) - f(x)) / h;
rightSide = df(x);
errList(i) = abs(leftSide - rightSide);
h = h*10^(-1);
end
and if you call it as :
err=diffConsistency(#sin,#cos,rand,10,1)
and plot(err), you can clearly see how the error gets reduced each smaller h.

How to write many functions depending on each other in matlab

I have some functions are depending on each ther , the functions are from this book page 136 http://www.cs.helsinki.fi/u/ahyvarin/papers/bookfinal_ICA.pdf .. I functions are presented below , How to write following functions in matlab ??
y(t) = W(t-1)*x(t)
h(t) = P(t-1)*y(t)
P(t)=(1/B)*Tri[P(t-1)-m(t)*h^T(t)]
m(t) = h(t)/(B+y^T(t))*h(t))
e(t) = x(t)-W^T(t-1)*y(t)
W(t) = W(t-1) + m(t)*e^T(t)
It is solving the weight matrix W(t) iteratively .. I tried to do like this in matlab but I did not work so may be you can advice to correct the code :
for i=1:10
e=randn(3,5000);
A=[1 0 0;-0.5 0.5 0;0.3 0.1 0.1];
x=A*e;
y(t) = W(t-1)*x(t)
h(t) = P(t-1)*y(t)
P(t)=(1/B)*Tri[P(t-1)-m(t)*h^T(t)]
m(t) = h(t)/(B+y^T(t))*h(t))
e(t) = x(t)-W^T(t-1)*y(t)
W(t) = W(t-1) + m(t)*e^T(t)
end
Thanks
Ok. I can't really understand what you want, but your code shows that you don't understand some moments. I will try to clarify some moments to you:
for i = 2:10
x = rand(3);
y = W(:,:,i-1)*x;
h = P(:,:,i-1)*y;
m=h/(1+y'*h);
P(:,:,i)=P(:,:,i-1)*m*h';
e=x-W(:,:,i-1)'*y;
W(:,:,i)=W(:,:,i-1)+m*e';
end
You must go something like this: 1. you calculate x and use it to calculate other functions.
2. all of them are matrices. So you need to define it first. For example y = ones(3) etc. 3.Thats not y^T or e^T. Its transposing. If you do not feel difference it's early for you to solve this task :)
And the last: Tri function will create a some kind of problems to you, but it's defined at 136 page.
P.S. i missed beta becouse of don't know what is it :)

Matlab optimiziation where objective is implicitly given by a fixed point equation

I have the following problem:
max CEQ(w) s.t. w in (0,1) and I don't know anything about CEQ(w) except that is given by a fixed point equation of the form CEQ(w) = F(CEQ(w)). If I fix a w, I can solve the fixed point equation using the fzero function and obtain a value for CEQ. If I choose a different w, I get another value for CEQ. Thus, I could loop over all possible values of w and then choose the one that gives the highest CEQ. This seems bad programming though and I was wondering whether I can do this more efficient in MATLAB: I want to model the solution to my fixed point equation as a function of w but I don't know how to implement it.
To be more precise, here is a sample code:
clear all
clc
NoDraws = 1000000;
T_hat = 12;
mu = 0.0058;
variance = 0.0017;
rf = 0.0036;
sim_returns(:,T_hat/12) = T_hat*mu + sqrt(T_hat*variance)*randn(NoDraws,1);
A = 5;
kappa=1;
l=0;
theta = 1 - l*(kappa^(1-A) - 1) *(kappa>1);
CEQ_DA_0 = 1.1;
CEQ_opt = -1000;
w_opt = 0;
W_T = #(w) (1-w)*exp(rf*T_hat) + w*exp(rf*T_hat + sim_returns(:,T_hat/12));
for w=0.01:0.01:0.99
W=W_T(w);
fp = #(CEQ) theta*CEQ^(1-A)/(1-A) - mean( W.^(1-A)/(1-A)) + l*mean( ((kappa*CEQ)^(1-A)/(1-A) - W.^(1-A)/(1-A)) .* (W < kappa*CEQ));
CEQ_DA = fzero(fp,CEQ_DA_0);
if CEQ_DA > CEQ_opt
CEQ_opt = CEQ_DA;
w_opt = w;
end
end
That is, in the loop, I fix a w, solve the fixed point equation and store the value for CEQ. If some other w gives a bigger value for CEQ, the current optimal w gets replaced by that new w. what I would like to have (instead of the loop part) is something like this:
fp = #(CEQ,w) theta*CEQ^(1-A)/(1-A) - mean( W_T(w).^(1-A)/(1-A)) + l*mean( ((kappa*CEQ)^(1-A)/(1-A) - W_T(w).^(1-A)/(1-A)) .* (W_T(w) < kappa*CEQ));
CEQ_DA = #(w) fzero(fp,CEQ_DA_0);
[w_opt, fval]=fminbnd(CEQ_DA,0,1);
Your proposed solution is very close. In words, you're defining fp as a function of two arguments, and would like CEQ_DA to be a function of w, which solves fp for CEQ, with that given w. The only issue is that fzero doesn't know which parameter of fp to solve over, because it can't match anonymous function parameters and fp parameters by name.
The answer is yet one more anonymous function inside the fzero, to turn fp(CEP,w) into fp_w(CEP), which will be solveable for CEQ
CEQ_DA = #(w) fzero(#(CEQ) fp(CEQ, w),CEQ_DA_0);

Angle between two vectors matlab

I want to calculate the angle between 2 vectors V = [Vx Vy Vz] and B = [Bx By Bz].
is this formula correct?
VdotB = (Vx*Bx + Vy*By + Vz*Bz)
Angle = acosd (VdotB / norm(V)*norm(B))
and is there any other way to calculate it?
My question is not for normalizing the vectors or make it easier. I am asking about how to get the angle between this two vectors
Based on this link, this seems to be the most stable solution:
atan2(norm(cross(a,b)), dot(a,b))
There are a lot of options:
a1 = atan2(norm(cross(v1,v2)), dot(v1,v2))
a2 = acos(dot(v1, v2) / (norm(v1) * norm(v2)))
a3 = acos(dot(v1 / norm(v1), v2 / norm(v2)))
a4 = subspace(v1,v2)
All formulas from this mathworks thread. It is said that a3 is the most stable, but I don't know why.
For multiple vectors stored on the columns of a matrix, one can calculate the angles using this code:
% Calculate the angle between V (d,N) and v1 (d,1)
% d = dimensions. N = number of vectors
% atan2(norm(cross(V,v2)), dot(V,v2))
c = bsxfun(#cross,V,v2);
d = sum(bsxfun(#times,V,v2),1);%dot
angles = atan2(sqrt(sum(c.^2,1)),d)*180/pi;
The traditional approach to obtaining an angle between two vectors (i.e. arccos(dot(u, v) / (norm(u) * norm(v))), as presented in some of the other answers) suffers from numerical instability in several corner cases. The following code works for n-dimensions and in all corner cases (it doesn't check for zero length vectors, but that's easy to add). See notes below.
% Get angle between two vectors
function a = angle_btw(v1, v2)
% Returns true if the value of the sign of x is negative, otherwise false.
signbit = #(x) x < 0;
u1 = v1 / norm(v1);
u2 = v2 / norm(v2);
y = u1 - u2;
x = u1 + u2;
a0 = 2 * atan(norm(y) / norm(x));
if not(signbit(a0) || signbit(pi - a0))
a = a0;
elseif signbit(a0)
a = 0.0;
else
a = pi;
end;
end
This code is adapted from a Julia implementation by Jeffrey Sarnoff (MIT license), in turn based on these notes by Prof. W. Kahan (page 15).
You can compute VdotB much faster and for vectors of arbitrary length using the dot operator, namely:
VdotB = sum(V(:).*B(:));
Additionally, as mentioned in the comments, matlab has the dot function to compute inner products directly.
Besides that, the formula is what it is so what you are doing is correct.
This function should return the angle in radians.
function [ alpharad ] = anglevec( veca, vecb )
% Calculate angle between two vectors
alpharad = acos(dot(veca, vecb) / sqrt( dot(veca, veca) * dot(vecb, vecb)));
end
anglevec([1 1 0],[0 1 0])/(2 * pi/360)
>> 45.00
The solution of Dennis Jaheruddin is excellent for 3D vectors, for higher dimensional vectors I would suggest to use:
acos(min(max(dot(a,b)/sqrt(dot(a,a)*dot(b,b)),-1),1))
This fixes numerical issues which could bring the argument of acos just above 1 or below -1. It is, however, still problematic when one of the vectors is a null-vector. This method also only requires 3*N+1 multiplications and 1 sqrt. It, however also requires 2 comparisons which the atan method does not need.