Graphing the result of NSolve - math

I'm trying to plot a parametric equation that was partially obtained using NSolve. Here's my attempted code:
VolumeDiff[v_] = 1.7 - v
SolveR[ v_] =
Re[NSolve[16 v^2 - 16 v*(r^3) + 3 (r^2) + 1 == 0, r, Reals]]
EnergyPos[r_] = r/2 (r + Sqrt[r^2 - 1])
EnergyNet[r_] = EnergyPos[SolveR[r]] + EnergyPos[SolveR[VolumeDiff[r]]]
ParametricPlot[{Re[EnergyNet[x]], 1.7 - 2. x}, {x, .1, 1.6}]
Basically, I have a cubic with two variables, I solve for one given the other and try to plot two parametric equations based on that original given variable. This is supposed to be a graph of energy vs. volume difference of two bubbles attached together. However, my axis are blank. I used NSolve to isolate the real root of the cubic equation and I guess Mathematica has a problem graphing with NSolve involved. I looked all over the internet but I couldn't find any answers to this. thanks for any help!
David

Several errors corrected.
You should read about how SetDelayed ( := ) and Solve[] work.
VolumeDiff[v_] := 1.7 - v
SolveR[v_] := NSolve[16 v^2 - 16 v*(r^3) + 3 (r^2) + 1 == 0, r, Reals][[1]]
EnergyPos[r_] := r/2 (r + Sqrt[r^2 - 1])
EnergyNet[r_] := EnergyPos[r /. SolveR[r]]+EnergyPos[r /. SolveR[VolumeDiff[r]]]
ParametricPlot[{EnergyNet[x], 1.7 - 2. x}, {x, .1, 2}]

Related

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.

Why does R density function return nonzero values outside the interval [from, to]?

I have entered into the R code of the density function, and I have noticed the following strange lines:
lo <- from - 4 * bw
up <- to + 4 * bw
To my understanding, they mean that the density is estimated on the interval [from - 4*bw, to + 4*bw] instead of [from, to].
To really understand what is going on, I have created a densityfun function, which copy-pastes the code of density, except at the end in order to return a function (you can find the R code on GitHub here). Then I get the following:
set.seed(1)
x <- rbeta(10000, 0.5, 0.5)
f <- densityfun(x, from = 0, to = 1)
f(-0.01) # 1.135904
Surprise: f(-0.01) is nonzero!
It also implies that the integral of f on [0, 1] is not 1:
integrate(f, 0, 1) # 0.8787954
integrate(f, -0.1, 1.1) # 0.997002
So why is the density function written that way (is it a bug?), and what could I do to avoid this behaviour (to have f(-0.01) = 0 in this example) without loosing any mass on f (to have integrate(f, 0, 1) approximately equal to 1 in this example)?
Thanks!
EDIT: I have changed a bit the values used in the example.

Given f(x) linear function, how to obtain a Quadratic Bezier control point

I've been doing a lot of research on the topic and found a couple of post that where helpful but I just can't get this right.
I am developing a very simple structural analysis app. In this app I need to display a graph showing the internal stress of the beam. The graph is obtained by the formula:
y = (100 * X / 2) * (L - X)
where L is the known length of the beam (lets say its 1 for simplicity). And X is a value between 0 and the Length of be beam. So the final formula would be:
y = (100 * X / 2) * (1 - x) where 0 < X < 1.
Assuming my start and end points are P0 = (0,0) and P2 = (1,0). How can I obtain P2 (control point)?? I have been searching in the Wikipedia page but I am unsure how to obtain the control point from the quadratic bezier curve formula:
B(t) = (1 - t)^2 * P0 + 2*(1 - t)*t * P1 + t^2 * P2
I'm sure it must be such an easy problem to fix… Can anyone help me out?
P.S.: I also found this, How to find the mathematical function defining a bezier curve, which seems to explain how to do the opposite of what I am trying to achieve. I just can't figure out how to turn it around.
We want the quadratic curve defined by y to match the quadratic Bezier curve
defined by B(t).
Among the many points that must match is the peak which occurs at x =
0.5. When x = 0.5,
y = (100 * x / 2) * (1 - x)
100 1 25
y = ---- * --- = ---- = 12.5
4 2 2
Therefore, let's arrange for B(0.5) = (0.5, 12.5):
B(t) = (1-t)^2*(0,0) + 2*(1-t)*t*(Px, Py) + t^2*(1,0)
(0.5, 12.5) = B(0.5) = (0,0) + 2*(0.5)*(0.5)*(Px, Py) + (0.25)*(1,0)
0.5 = 0.5 * Px + 0.25
12.5 = 0.5 * Py
Solving for Px and Py, we get
(Px, Py) = (0.5, 25)
And here is visual confirmation (in Python) that we've found the right point:
# test.py
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
y = (100*x/2)*(1-x)
t = np.linspace(0, 1, 100)
P0 = np.array([0,0])
P1 = np.array([0.5,25])
P2 = np.array([1,0])
B = ((1-t)**2)[:,np.newaxis]*P0 + 2*((1-t)*t)[:,np.newaxis]*P1 + (t**2)[:,np.newaxis]*P2
plt.plot(x, y)
plt.plot(B[:,0], B[:,1])
plt.show()
Running python test.py, we see the two curves overlap:
How did I know to choose t = 0.5 as the parameter value when B(t) reaches its maximum height?
Well, it was mainly based on intuition, but here is a more formal way to prove it:
The y-component of B'(t) equals 0 when B(t) reaches its maximum height. So, taking the derivative of B(t), we see
0 = 2*(1-2t)*Py
t = 0.5 or Py = 0
If Py = 0 then B(t) is a horizontal line from (0,0) to (1,0). Rejecting this degenerate case, we see B(t) reaches its maximum height when t = 0.5.
Your quadratic bezier curve formula has a typo in the middle term. It should be:
B(t) = (1 - t)^2 * P0 + 2 * (1 - t) * t * P1 + t^2 * P2
This means you should take the P1=(1,50) that #unutbu found and divide the coordinates in half to get P1=(.5,25). (This won't matter if you're plotting the parametric equation on your own, but if you want something like LaTeX's \qbezier(0,0)(.5,25)(1,0), then you'll need the corrected point.)
The P1 control point is defined so that the tangent lines at P0 and P2 intersect at P1. Which means that if (P1)x=(P2)x, the graph should be vertical on its righthand side (which you don't want).
In response to your comment, if you have a quadratic y=f(x), then it is symmetrical about its axis (almost tautologically). So the maximum/minimum will occur at the average of the roots (as well as the control point).

What is being done in here ? (Used math recognition)

I know this isn't exactly programming related per se, but programmers are the most
probable of all people who will recognize this maybe.
I have the following (X and Y are arrays, both with 3 elements), and I cannot recognize (although it reminds me of a few things, but none quite!) what is being done here. Does it ring any bells for anyone else ?
I gather you can disregard the lower part; the upper should probably give it away ... but I still cannot see it.
At first it reminded me of linear interpolation in 3d space ...
SUBROUTINE TRII(X,Y,XR,YR)
DIMENSION X(3),Y(3)
D=X(1)*(X(2)**2-X(3)**2)+
> X(2)*(X(3)**2-X(1)**2)+
> X(3)*(X(1)**2-X(2)**2)
D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
> Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
> Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)
D2=Y(1)*(X(2)**2-X(3)**2)+
> Y(2)*(X(3)**2-X(1)**2)+
> Y(3)*(X(1)**2-X(2)**2)
D3=X(2)*(Y(3)-Y(1))+
> X(1)*(Y(2)-Y(3))+
> X(3)*(Y(1)-Y(2))
A=D1/D
B=D2/D
C=D3/D
YR=A+B*XR+C*XR**2
RETURN
END
SUBROUTINE TRIM(X,Y,XR,YR,XM,YM)
DIMENSION X(3),Y(3)
D=X(1)*(X(2)**2-X(3)**2)+
> X(2)*(X(3)**2-X(1)**2)+
> X(3)*(X(1)**2-X(2)**2)
D1=Y(1)*(X(2)*X(3)**2-X(3)*X(2)**2)+
> Y(2)*(X(3)*X(1)**2-X(1)*X(3)**2)+
> Y(3)*(X(1)*X(2)**2-X(2)*X(1)**2)
D2=Y(1)*(X(2)**2-X(3)**2)+
> Y(2)*(X(3)**2-X(1)**2)+
> Y(3)*(X(1)**2-X(2)**2)
D3=X(2)*(Y(3)-Y(1))+
> X(1)*(Y(2)-Y(3))+
> X(3)*(Y(1)-Y(2))
A=D1/D
B=D2/D
C=D3/D
XR=-B/(2.*C)
YR=A+B*XR+C*XR**2
XM=XR
IF(XR.GT.X(1).OR.XR.LT.X(3))XM=X(1)
YM=A+B*XM+C*XM**2
IF(YM.LT.Y(1))XM=X(1)
IF(YM.LT.Y(1))YM=Y(1)
RETURN
END
">" is a continuation sign.
The code run as follows
Routine TRII takes as input the coordinates of three points (x,y) and interpolates a parabola using Lagrange interpolation. Also takes as input the coordinate XR. Returns in YR the value at XR for the interpolating parabola.
I guess the name of the routine comes from "TRI" (Croatian for "three" (points)) and "I" for Interpolation.
Routine TRIM also calculates the same parabola, and returns the minimun value of the function in the interval {X(1),X(3)}.The name comes from "TRI" and "M" (minimum)
(I "really" executed the program) >)
Note that this is FORTRAN code and the parameters are passed by reference, so the results are returned back in the same parameters (very odd!)
Edit
Just for fun, let's run TRII
TRII[X_, Y_, XR_] :=
Module[{D0, D1, D2, D3, A, B, C},
D0 = X[[1]]*(X[[2]]^2 - X[[3]]^2) +
X[[2]]*(X[[3]]^2 - X[[1]]^2) +
X[[3]]*(X[[1]]^2 - X[[2]]^2);
D1 = Y[[1]]*(X[[2]]*X[[3]]^2 - X[[3]]*X[[2]]^2) +
Y[[2]]*(X[[3]]*X[[1]]^2 - X[[1]]*X[[3]]^2) +
Y[[3]]*(X[[1]]*X[[2]]^2 - X[[2]]*X[[1]]^2);
D2 = Y[[1]]*(X[[2]]^2 - X[[3]]^2) +
Y[[2]]*(X[[3]]^2 - X[[1]]^2) +
Y[[3]]*(X[[1]]^2 - X[[2]]^2);
D3 = X[[2]]*(Y[[3]] - Y[[1]]) +
X[[1]]*(Y[[2]] - Y[[3]]) +
X[[3]]*(Y[[1]] - Y[[2]]);
A = D1/D0;
B = D2/D0;
C = D3/D0;
Return[A + B*XR + C*XR^2];];
X = RandomReal[1, 3];
Y = RandomReal[1, 3];
Show[Plot[TRII[X, Y, x], {x, 0, 1}],
ListPlot[Transpose[{X, Y}], PlotMarkers -> Automatic]]
D is the determinant of the matrix:
| x(1) x(1)² 1 |
D = det | x(2) x(2)² 1 |
| x(3) x(3)² 1 |
In D1, the rightmost column has been replaced with Y:
| x(1) x(1)² Y(1) |
D1 = det | x(2) x(2)² Y(2) |
| x(3) x(3)² Y(3) |
In D2, and D3 it's the first and second columns, respectively. Is it easier to recognize now? Looks a lot like using Cramer's rule to solve a linear equation to me.
Edit: To be more precise: (A, B, C) is the solution to the system:
A + x(1)*B + x(1)²*C = Y(1)
A + x(2)*B + x(2)²*C = Y(2)
A + x(3)*B + x(3)²*C = Y(3)
YR is the square of the solution to the quadratic equation (nb, different x!):
C*x² + B*x + A = 0
I feel like this should be obvious now, but I can't quite grasp it...
This code represents a kind of interpolation/quadratic curve fitting on three 2d points together with a way to compute the minimum or maximum value of such a fitted quadratic within the interval itself. I guess that TRII stands for triple (point)-interpolation and TRIM stands for triple (point) minimum or maximum.
To be more precised TRII solves the problem :- find a quadratic curve that passes through the points (x1,y1),(x2,y2) and (x3,y3) in the form Y=A+BX+CX^2 and compute the Y value of the quadratic at the point XR and return as YR. This is basically a way to interpolate smoothly between three 2d points. It is often used to find a better approximation for the max or min value of a set of discrete data points.
All the D, D1, D2, D3 stuff is to solve the matrix equation:
(1 X1 X1^2) *(A) = (Y1)
(1 X2 X2^2) *(B) = (Y2)
(1 X3 X3^2) *(C) = (Y3)
using Cramers rule as mentioned in one of the other comments, D is the matrix determinant and D1, D2, D3 are co-factors.
TRIM again computes the quadratic Y=A+BX+CX^2 and then finds a max/min of this quadratic (XM, YM). This is done by initially finding the point where the quadratic has a turning point: if F(X)=A+BX+CX^2, F'(XR)=B+2*C*XR=0, or XR=-B/2*C, YR=A+BXR+CXR^2. There is then some logic to force the returned XM, YM min or max values to lie within certain bounds.
The code:
XM=XR
.
.
.
IF(YM.LT.Y(1))YM=Y(1)
Is a little weird since if we assume that GT and LT mean greater than and less than respectively then we need to assume that X3'<'X1 otherwise the condition (XR.GT.X(1).OR.XR.LT.X(3)) is trivial and XM,YM are set to X1, Y1.
So X3'<'X1 and the condition says that if the quadratics max/min value is outside the interval (X1,X3) then set (XM,YM) to (X1, Y1) as before. If not then if Y1 is above the min/max value in Y then again set (XM,YM) to (X1, Y1).
It is hard to understand what this means and I suspect the code may be wrong! Any thoughts?
Ivan
I'm not sure what language this is, but it's clear that this is some sort of solver for quadratic equations. The XR and YR expressions are a dead giveaway:
XR = -B / (2.*C)
YR = A + B*XR + C*XR**2
Without knowing what the X(1..3) and Y(1..3) expressions are, however, it's not going to be possible to infer too much more about what the A/B/C coefficients represent, however. Lots of things use quadratic equations -- area of a circle given the radius, intensity of light at a given distance, et cetera. More contextual data is required.
Update: The OP indicated that he can't be too much more specific for secrecy reasons. Here are some hints, though:
What does the subroutine return? How are those results used later on? That may lead to better insights.
It appears that Y(1) is some sort of magic lower bound for the result of this computation. Notice that if YM is less than Y(1), then both XM and YM are set to X(1) and Y(1), respectively.
The "D" expressions look like this, in more natural syntax:
d = x1 * [x2^2 - x3^2] + x2 * [x3^2 - x1^2] + x3 * [x1^1 - x2^2]
d1 = y1 * [x2*x3^2 - x3*x2^2] + y2 * [x3*x1^2 - x1*x3^2] + y3 * [x1*x2^2 - x1*x2^2]
d2 = y1 * [x2^2 - x3^2] + y2 * [x3^2 - x1^2] + y3 * [x1^2 - x2^2]
d3 = x2 * [y3 - y1] + x1 * [y2 - y3] * x3 * [y1 - y2]
This looks very much like some sort of matrix operation; D is almost certainly for "determinant". But there are other things that have the same mathematical relationship.
This is a way to solve linear equation systems, specifically cramers rule. Also have a look at the rule of sarrus. After that, you seem to construct a quadratic equation out of it.

Find point of intersection between two vectors in MATLAB

I have a very simple MATLAB question. What is the easiest way to find the point of intersection between two vectors. I am not familiar with the various MATLAB functions -- it seems like there should be one for this.
For example, if I have one vector from (0,0) to (6,6) and another vector from (0,6) to (6,0), I need to determine that they intersect at (3,3).
One solution is to use the equations derived in this tutorial for finding the intersection point of two lines in 2-D (update: this is an internet archive link since the site no longer exists). You can first create two matrices: one to hold the x coordinates of the line endpoints and one to hold the y coordinates.
x = [0 0; 6 6]; %# Starting points in first row, ending points in second row
y = [0 6; 6 0];
The equations from the above source can then be coded up as follows:
dx = diff(x); %# Take the differences down each column
dy = diff(y);
den = dx(1)*dy(2)-dy(1)*dx(2); %# Precompute the denominator
ua = (dx(2)*(y(1)-y(3))-dy(2)*(x(1)-x(3)))/den;
ub = (dx(1)*(y(1)-y(3))-dy(1)*(x(1)-x(3)))/den;
And you can now compute the intersection point of the two lines:
xi = x(1)+ua*dx(1);
yi = y(1)+ua*dy(1);
For the example in the question, the above code gives xi = 3 and yi = 3, as expected. If you want to check that the intersection point lies between the endpoints of the lines (i.e. they are finite line segments), you just have to check that the values ua and ub both lie between 0 and 1:
isInSegment = all(([ua ub] >= 0) & ([ua ub] <= 1));
A couple more points from the tutorial I linked to above:
If the denominator den is 0 then the two lines are parallel.
If the denominator and numerator for the equations for ua and ub are 0 then the two lines are coincident.
Well, you really have two points on two different lines, and you want to find the intersection. The easiest way is to find the equations of the two lines and then calculate the intersection.
The equation of a line is given by y = mx + b where m is the slope and b is the y-intercept. For one line you have two points which gives two equations. So, you can solve for the constants m and b. This gives the following two equations:
0 = 0*m + 1*b % Using the first point x=y=0 into y=m*x+b
6 = 6*m + 1*b % Using the second point x=y=6
Or in matrix form:
[ 0 ] = [ 0 1 ]* [ m ]
[ 6 ] [ 6 1 ] [ b ]
For the first line the constants can be calculated in MATLAB by
C1 = inv([0 1;6 1]*[1;0]; % m=C1(1) and b=C(2)
Now that you have the equation for the two lines you can solve for the intersection by solving the following system of equations (which are obtained by manipulating the equation for a line):
m_1*x-y = -b_1
m_2*x-y = -b_2
All that is left is to write the above system of equations in matrix form and solve:
[x] = inv [m_1 -1] * [-b_1]
[y] [m_2 -1] [-b_2]
Or in MATLAB syntax:
I = inv([m_1 -1; m_2 -1])*[-b_1;-b_2]; % I is the intersection.
Notes
As per gnovice's comment if the lines are actually line segments you need to check if the intersection is between the end points of the line segments.
If the two slopes are equal, m_1 = m_2, then there will either be no intersection or infinitely many intersections.
For a general multi-dimensional solution, what you're actually doing is solving a series of linear systems.
First you need to reduce the equations to linear form: Ax+By=C (expand dimensions as necessary)
For two-points:
y - y1 = (y2 - y1) / (x2 - x1) * (x - x1)
y - y1 = (y2 - y1) / (x2 - x1) * x - (y2 - y1) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y - y1 = (y1 - y2) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y = (y1 - y2) / (x2 - x1) * x1 + y1
(y1 - y2) * x + (x2 - x1) * y = (y1 - y2) * x1 + (x2 - x1) * y1
A = (y1 - y2)
B = (x2 - x1)
C = (y1 - y2) * x1 + (x2 - x1) * y1 = A * x1 + B * y1
For your example:
x1 = 0, x2 = 6, y1 = 0, y2 = 6
A1 = (0 - 6) = -6
B1 = (6 - 0) = 6
C1 = A1 * 0 + B1 * 0 = 0
x1 = 0, x2 = 6, y1 = 6, y2 = 0
A2 = (6 - 0) = 6
B2 = (6 - 0) = 6
C2 = A2 * 0 + B2 * 6 = 6 * 6 = 36
Then, form a matrix, with A B and C in rows:
[A1 B1 C1]
[A2 B2 C2]
[-6 6 0]
[ 6 6 36]
Now reduce to reduced echelon form using the Matlab function rref(matrix):
[ 1 0 3]
[ 0 1 3]
As you can guess, the last column is your intersection point. This is expandable to as many dimensions as necessary. If your reduced echelon form has something other than the identity matrix for the front part of it, your vectors either do not have a unique intersection point, or have no intersection point, depending on the form of the matrix.
dim = 2;
% Do other stuff, ending with rref(matrix)
if (matrix(:,1:dim) == eye(dim))
% Matrix has unique solution.
solution = (matrix(:,dim+1))'
else
% No unique solution.
end
In two dimensions, the variations are:
Linear solution, indicating solution is a line of form x + By = C:
[ 1 B C]
[ 0 0 0]
No solution, indicating the lines do not cross, where C2 <> 0:
[ 1 B C1]
[ 0 0 C2]
The other results are confusing, verbose and incomplete, IMO. So here's my two cents - also potentially confusing and verbose.
If you are sure that your lines are not skew-parallel or parallel, the following is all you need:
% Let each point be def as a 3x1 array
% Let points defining first line be : p1, q1
% Let points defining second line be : p2, q2
L = p1-p2;
M = p1-q1;
N = p2-q2;
A = [M N];
T = pinv(A)*L;
h = p1-T(1)*(p1-q1); % h is a 3x1 array representing the actual pt of intersection
Yeah, the Moore-Penrose pseudoinverse is a powerful thing. The explanation for the approach is: You want to find the weights or the scaling factors of the 'direction vectors' (M and N are direction vectors), that linearly combine M and N to give L.
A full description is presented below. It presents a simple exception detection scheme, and their handling is left to the user. (The minimum distance between two line algorithms is from Wikipedia; the comparison of direction cosines (DCS) to check vector attitudes is common knowledge.)
% Let each point be def as a 3x1 array
% Let points defining first line be : p1, q1
% Let points defining second line be: p2, q2
% There are two conditions that prevent intersection of line segments/lines
% in L3 space. 1. parallel 2. skew-parallel (two lines on parallel planes do not intersect)
% Both conditions need to be identified and handled in a general algorithm.
% First check that lines are not parallel, this is done by comparing DCS of
% the line vectors
% L, M, N ARE DIRECTION VECTORS.
L = p1-p2;
M = p1-q1;
N = p2-q2;
% Calculate a normalized DCS for comparison. If equal, it means lines are parallel.
MVectorMagnitude = sqrt(sum(M.*M,2)); % The rowsum is just a generalization for N-D vectors.
NVectorMagnitude=sqrt(sum(N.*N,2)); % The rowsum is just a generalization for N-D vectors.
if isequal(M/MVectorMagnitude,N/NVectorMagnitude) % Compare the DCS for equality
fprintf('%s\n', 'lines are parallel. End routine')
end;
% Now check that lines do not exist on parallel planes
% This is done by checking the minimum distance between the two lines. If there's a minimum distance, then the lines are skew.
a1 = dot(M,L); b1 = dot(M,M); c1 = dot(M,N);
a2 = dot(N,L); b2 = dot(N,M); c2 = dot(N,N);
s1 = -(a1*c2 - a2*c1)/(b1*c2-b2*c1);
s2 = -(a1*b2 - a2*b1)/(b1*c2-b2*c1);
Sm = (L + s1*M - s2*N);
s = sqrt(sum(Sm.*Sm,2));
if ~isequal(s,0) % If the minimum distance between two lines is not zero, then the lines do not intersect
fprintf('%s\n','lines are skew. End routine')
end;
% Here's the actual calculation of the point of intersection of two lines.
A = [M N];
T = pinv(A)*L;
h = p1-T(1)*(p1-q1); % h is a 3x1 array representing the actual pt of intersection.
So the pinv approach will give you results even when your M and N vectors are skew (but not parallel, because inv(A'.A) is required to exist). You can use this to determine the minimum distance between two parallel lines or between two parallel planes - to do this, define k = p2+T(2)*(p2-q2), and then the required distance is h-k. Also note that h and k are the points on the lines that are closest to each other IFF lines are skew.
So the use of the pseudoinverse and projection spaces gives us a concise algorithm for:
Determining the point of intersection of two lines (not parallel, and not skew)
Determining the minimum distance between two lines (not parallel)
Determining the points closest to each other on two skew lines.
Concise is not the same as time-efficient. A lot depends on your exact pinv function implementation - MATLAB uses svd which solves to a tolerance. Also, some results will only be approximately accurate in higher dimensions and higher order definitions of the measurement metric (or vector norms). Besides the obvious dimension independent implementation, this can be used in statistical regression analysis and algebraically maximizing likelihood of point estimates.

Resources