get data spread/stddev from singular value decomposition with weighted least squares - math

I have a scalarfield which has been discretized into a grid of voxels. I am trying to fit a specific 3d function to that scalarfield. The 3d function I want to fit is defined by a plane and a gaussian fall-off per distance to that plane. Just to be clear: I am not talking about fitting a plane surface to a scalarfield but about fitting a 3d function defined by a plane and a fall-off (kind of a fuzzy plane or a band).
So far I managed to find the plane parameters. I do this by plugging all voxel positions and their scalar values of the input field into a weighted least squares problem. I am roughly following this procedure here: Weighted least square - fit a plane to 3D point set. The difference is that my point set consists of all the voxel centers weighted by their respective input scalarfield values. It seems to work pretty well and I am getting nice reasonable plane parameters.
My question now is about finding the standard deviation for my gaussian fall-off function. What is interesting is that the singular values from SVD actually relate to the spread of the data in the local coordinate system of the plane. This relationship has been discussed here: Can I get data spread (noise) from singular value decomposition?. The difference to my problem is that I am working with a weighted least squares problem and when I divide the singular values by the square root of the weighted sum, my standard deviation is roughly doing the right thing but still is quite off.
I basically would like to know if there is a formal relationship between the singular values of a SVD and the standard deviation of samples from a plane given by a weighted least squares fit. In particular, can I expect to be able to exactly reconstruct the plane and standard deviation parameter when the input scalarfield has been created from such a parameterization?
Thanks,
David

Related

Getting the boundary of a Bezier curve

I have points list and control points list to draw a Bezier curve.
Please let me know how to calculate the boundary rectangle of the Bezier curve.
var pointsList = [CGPoint(34, 23), ... , CGPoint(23, 85)]
var controlPoints = [CGPoint(45, 34), ..., CGPoint(55, 99)]
Normally not really a hard problem, covered over on http://pomax.github.io/bezierinfo/#boundingbox:
Compute the x and y derivatives, which is super easy to do,
Find all roots (derivative=0) for both derivatives, let's call those the sets r{x} and r{y}, then
Compute the corresponding value sets bezier{x} and bezier{y} for those roots. Then,
Your bounding box has corners defined by the lowest and highest values min/max values in those sets.
In this, only step 2 might be a bit tricky if you're using high order bezier curves. Once your curve consists of more than four points, you can't use symbolic maths to find the roots and it's far easier to just run through the derivative curve and see where the resulting coordinates have a value close enough to zero to treat them as approximate root.
Your graphic looks like it's simply a series of connected cubic Bezier curves, in which case the root finding is easy (the derivatives will be quadratic curves, you learn how to find the roots for those in high school using the quadratic equation), and the box procedure is simply "compute the bounding box for each cubic curve section, and when you're done, the full bounding box simply uses the min/max values across all individual boxes".

hyperplane equation in SVM

How does the SVM algorithm find the optimum hyperplane? The positive margin hyperplane equation is w.x-b=1, the negative margin hyperplane equation is w.x-b=-1, and the middle(optimum) hyperplane equation is w.x-b=0).
I understand how a hyperplane equation can be got by using a normal vector of that plane and a known vector point(not the whole vector) by this tutorial. Lets say the known vector point is x1, the whole vector will be (x-x1), for some x. If w is the normal vector of the plane, then w.(x-x1)=0; eventually we will get the form w.x=b
Now, for getting a hyperplane, we need a normal vector and known point. How does the algorithm create a hyperplane at the middle where there is no data point (which I think is a known vector point needed in the equation) from training data?
Maybe I misunderstand something or my logic is not correct.
You misunderstand one basic fact: the algorithm is not required to represent a hyperplane in terms of w.x-b = 0, using a given data point. The algorithm is free to change this into any form convenient to each of its functions.
The solution is obvious, as you've already found it: the algorithm does not have to use one of the points form the data set. In fact, if the partition is ideal (no data on the wrong side), there is no point in the middle.
However, finding that hyperplane is trivial. (1) The positive and negative hyperplanes are parallel, and (2) the optimum plane bisects their separation. By (1), all three planes have the same normal vector. By (2), the reference point can be the midpoint of any segment connecting two points on opposite planes.
Briefly, pick a positive support vector and a negative support vector; these lie one on each of the planes. Find the midpoint between them, convolve with the normal vector, and there's your optimum plane.

Creating a smooth nurb from list of points

I am developing a 3D graphic application in which the user can draw curves.
I record the curve that is drawn by the user and i would like to create a smooth nurb from the recorded set of points.
I tried using the openNurbs library but i could not find a way to do the fitting using the library.
How can i fit a set of points to a nurb?
First of all, I don't think you need nurbs. Fitting a B-spline curve to your data points should be good enough.
If you only have a few dozen points, then it is likely you would like the B-spline curve to exactly pass thru these data points. In this case, you are looking for spline interpolation algorithms. If this is the case, you can use Catmull Rom spline or Overhauser spline to interpolate your data points. Both will create C1 cubic splines and both are easy to implement without the need to solve a linear equation set.
If you have several hundreds of points, then it is likely that you only want the B-spline curve to lie close to the data points. Then, the algorithm you are looking for is least square fitting. You can find plenty of articles (e.g.: link1 ) in this area online. A typical algorithm for least square fitting with B-spline curve will involve these steps:
1) Choose a parametrization for your data points. Chord length parametrization is typically a good choice for least square fitting.
2) Choose the degree for the B-spline. Typically, we use degree 3, i.e., cubic B-spline.
3) Decide number of control points for your B-spline.
4) Decide the knot vector based on the information in the first 3 steps.
5) Solve a linear equation set to find the control points of the B-spline.

Slerp with more than two points

The correct way to interpolate between two points on a sphere is using slerp.
How would one interpolate between more than two points on a sphere? So summing a set of points with different weights on the surface of a sphere?
Simply summing the points multiplied by their weights and then normalising the result is not accurate enough when the angles are large. We need 'true' spherical interpolation.
I asked this question on math.stackexchange.com, and someone found a paper that describes exactly this. Here it is: Spherical Averages and Applications to Spherical Splines and Interpolation
The problem I see is:
Slerp gives constant velocity. That is, a given increment in your interpolation parameter gives you the same distance on the sphere, regardless of where you are on the [0,1] range.
Unfortunately, because the sphere is curved, you can't do this for more than one interpolation parameter. Either you need to give up constant velocity, or give up interpolating with more than one parameter.
You may be able to find an interpolation function that isn't constant velocity that nonetheless satisfies your requirements. But because of the above problem, I don't think it will correspond directly and symmetrically to the 1-D slerp.

Optimal rotation of 3D model for 2D projection

I'm looking for a way to determine the optimal X/Y/Z rotation of a set of vertices for rendering (using the X/Y coordinates, ignoring Z) on a 2D canvas.
I've had a couple of ideas, one being pure brute-force involving performing a 3-dimensional loop ranging from 0..359 (either in steps of 1 or more, depending on results/speed requirements) on the set of vertices, measuring the difference between the min/max on both X/Y axis, storing the highest results/rotation pairs and using the most effective pair.
The second idea would be to determine the two points with the greatest distance between them in Euclidean distance, calculate the angle required to rotate the 'path' between these two points to lay along the X axis (again, we're ignoring the Z axis, so the depth within the result would not matter) and then repeating several times. The problem I can see with this is first by repeating it we may be overriding our previous rotation with a new rotation, and that the original/subsequent rotation may not neccesarily result in the greatest 2D area used. The second issue being if we use a single iteration, then the same problem occurs - the two points furthest apart may not have other poitns aligned along the same 'path', and as such we will probably not get an optimal rotation for a 2D project.
Using the second idea, perhaps using the first say 3 iterations, storing the required rotation angle, and averaging across the 3 would return a more accurate result, as it is taking into account not just a single rotation but the top 3 'pairs'.
Please, rip these ideas apart, give insight of your own. I'm intreaged to see what solutions you all may have, or algorithms unknown to me you may quote.
I would compute the principal axes of inertia, and take the axis vector v with highest corresponding moment. I would then rotate the vertices to align v with the z-axis. Let me know if you want more details about how to go about this.
Intuitively, this finds the axis about which it's hardest to rotate the points, ie, around which the vertices are the most "spread out".
Without a concrete definition of what you consider optimal, it's impossible to say how well this method performs. However, it has a few desirable properties:
If the vertices are coplanar, this method is optimal in that it will always align that plane with the x-y plane.
If the vertices are arranged into a rectangular box, the box's shortest dimension gets aligned to the z-axis.
EDIT: Here's more detailed information about how to implement this approach.
First, assign a mass to each vertex. I'll discuss options for how to do this below.
Next, compute the center of mass of your set of vertices. Then translate all of your vertices by -1 times the center of mass, so that the new center of mass is now (0,0,0).
Compute the moment of inertia tensor. This is a 3x3 matrix whose entries are given by formulas you can find on Wikipedia. The formulas depend only on the vertex positions and the masses you assigned them.
Now you need to diagonalize the inertia tensor. Since it is symmetric positive-definite, it is possible to do this by finding its eigenvectors and eigenvalues. Unfortunately, numerical algorithms for finding these tend to be complicated; the most direct approach requires finding the roots of a cubic polynomial. However finding the eigenvalues and eigenvectors of a matrix is an extremely common problem and any linear algebra package worth its salt will come with code that can do this for you (for example, the open-source linear algebra package Eigen has SelfAdjointEigenSolver.) You might also be able to find lighter-weight code specialized to the 3x3 case on the Internet.
You now have three eigenvectors and their corresponding eigenvalues. These eigenvalues will be positive. Take the eigenvector corresponding to the largest eigenvalue; this vector points in the direction of your new z-axis.
Now, about the choice of mass. The simplest thing to do is to give all vertices a mass of 1. If all you have is a cloud of points, this is probably a good solution.
You could also set each star's mass to be its real-world mass, if you have access to that data. If you do this, the z-axis you compute will also be the axis about which the star system is (most likely) rotating.
This answer is intended to be valid only for convex polyhedra.
In http://203.208.166.84/masudhasan/cgta_silhouette.pdf you can find
"In this paper, we study how to select view points of convex polyhedra such that the silhouette satisfies certain properties. Specifically, we give algorithms to find all projections of a convex polyhedron such that a given set of edges, faces and/or vertices appear on the silhouette."
The paper is an in-depth analysis of the properties and algorithms of polyhedra projections. But it is not easy to follow, I should admit.
With that algorithm at hand, your problem is combinatorics: select all sets of possible vertexes, check whether or not exist a projection for each set, and if it does exists, calculate the area of the convex hull of the silhouette.
You did not provide the approx number of vertex. But as always, a combinatorial solution is not recommended for unbounded (aka big) quantities.

Resources