Calculate arc length of piecewise cubic spline? - c

I would like to calculate the arc length of an already-interpolated piecewise cubic spline, where each segment is defined by a normal cubic polynomial ax^3 + bx^2 + cx + d. I am not sure, however, what the best route to take is.
My first idea is to use numerical integration and the following arc length formula to calculate the arc length for each segment and then sum them up:
https://tutorial.math.lamar.edu/classes/calcii/arclength.aspx
I am not sure if this is the best approach, as I have minimal experience in numeric integration. If this is the approach to take, which numeric integration method should I use? If not, how can I accomplish this?
Thanks a lot

There is a closed-form expression in terms of the Elliptic integrals, but the exact computation is better done by Mathematica, and next you will need the elliptic functions handy.
The numerical method by polyline approximation (as in the link) is a little too elementary. For such a smooth function, Simpson's rule will be fine. https://en.wikipedia.org/wiki/Simpson%27s_rule

Related

How to obtain the derivative of Rodrigues vector and perform update in nonlinear least square?

I am now interested in the bundle adjustment in SLAM, where the Rodrigues vectors $R$ of dimension 3 are used as part of variables. Assume, without loss of generality, we use Gauss-Newton method to solve it, then in each step we need to solve the following linear least square problem:
$$J(x_k)\Delta x = -F(x_k),$$
where $J$ is the Jacobi of $F$.
Here I am wondering how to calculate the derivative $\frac{\partial F}{\partial R}$. Is it just like the ordinary Jacobi in mathematic analysis? I have this wondering because when I look for papers, I find many other concepts like exponential map, quaternions, Lie group and Lie algebra. So I suspect if there is any misunderstanding.
This is not an answer, but is too long for a comment.
I think you need to give more information about how the Rodrigues vector appears in your F.
First off, is the vector assumed to be of unit length.? If so that presents some difficulties as now it doesn't have 3 independent components. If you know that the vector will lie in some region (eg that it's z component will always be positive), you can work round this.
If instead the vector is normalised before use, then while you could then compute the derivatives, the resulting Jacobian will be singular.
Another approach is to use the length of the vector as the angle through which you rotate. However this means you need a special case to get a rotation through 0, and the resulting function is not differentiable at 0. Of course if this can never occur, you may be ok.

Inverse matrix calculation in real time

I have been developing a C language control software working in real time. The software implements among others discrete state space observer of the controlled system. For implementation of the observer it is necessary to calculate inverse of the matrix with 4x4 dimensions. The inverse matrix calculation has to be done each 50 microseconds and it is worthwhile to say that during this time period also other pretty time consuming calculation will be done. So the inverse matrix calculation has to consume much less than 50 microseconds. It is also necessary to say that the DSP used does not have ALU with floating point operations support.
I have been looking for some efficient way how to do that. One idea which I have is to prepare general formula for calculation the determinant of the matrix 4x4 and general formula for calculation the adjoint matrix of the 4x4 matrix and then calculate the inverse matrix according to below given formula.
What do you think about this approach?
As I understand the consensus among those who study numerical linear algebra, the advice is to avoid computing matrix inverses unnecessarily. For example if the inverse of A appears in your controller only in expressions such as
z = inv(A)*y
then it is better (faster, more accurate) to solve for z the equation
A*z = y
than to compute inv(A) and then multiply y by inv(A).
A common method to solve such equations is to factorize A into simpler parts. For example if A is (strictly) positive definite then the cholesky factorization finds lower triangular matrix L so that
A = L*L'
Given that we can solve A*z=y for z via:
solve L*u = y for u
solve L'*z = u for z
and each of these is easy given the triangular nature of L
Another factorization (that again only applies to positive definite matrices) is the LDL which in your case may be easier as it does not involve square roots. It is described in the wiki article linked above.
More general factorizations include the LUD and QR These are more general in that they can be applied to any (invertible) matrix, but are somewhat slower than cholesky.
Such factorisations can also be used to compute inverses.
To be pedantic describing adj(A) in your post as the adjoint is, perhaps, a little old fashioned; I thing adjugate or adjunct is more modern. In any case adj(A) is not the transpose. Rather the (i,j) element of adj(A) is, up to a sign, the determinant of the matrix obtained from A by deleting the i'th row and j'th column. It is awkward to compute this efficiently.

How to find the roots of a function whose analytical form is not known, rather the function is available as a tabulated set of values?

To find the roots of a function, we can generally use bisection method or Newton's method. For a function f(x), this is possible only when we have an analytical expression for the x-dependence of f(x).
I am trying to find the roots of such a function where I don't know the exact form of the function, rather I have a tabulated data for the values of f(x) for each values of x in a particular range of x. I am writing my program in C and I am using a for-loop to calculate f(x) for each value of x by solving a non-linear equation using bisection method and tabulating the data. Now I need to find the roots of the function f(x).
Can anyone help me with any suitable method or algorithm for the problem?
Thanks in advance!
You know from where the sign changes that a root has to be between two points.
Take several nearby points, put a polynomial through them, and then solve for the root of that polynomial using Newton's method.
From your description it looks like you should be able to calculate your function at this new point. If so, then I would suggest that you calculate the value at this point, add the two nearest neighbors, calculate a parabola and solve for the root of that. If your function is smooth and has a non-zero derivative at the root, this step will make your estimate of the root several orders of magnitude more accurate.
(You can repeat again for even more accuracy. But the increased accuracy at this point may be on par with the numerical errors in your estimate of the value of the function.)

Defining Unit Vectors in Spherical Coordinates for use with Eigen3

I'm posting here because I'm at a bit of a loss
I'm trying to implement a solution to Maxwells equations (p47 2-2)
,
which is given in Spherical coordinates in C++ so it may be used in a larger modeling project. I'm using Eigen3 as a base for linear algebra, which as far as I can find doesn't explicitly support spherical coordinates (I'm open to alternatives)
To implement the solution I need (or at least i think i need) to define the spherical unit vectors as spherical coordinates however, as they're not constants like in Cartesian Coordinates and I don't understand how to do this.
I'm hesitant to convert the solution to Cartesian coordinates as I don't think I understand the implications of doing this (is it even valid?)
Any and all input and advice is appreciated
The solution, which seems obvious now I have found it, is to implement Spherical Unit Vector Identities as 3 functions (one for each unit vector) that takes r, Theta, and Phi as arguments and return a vector.

Raise matrix to complex power

I'm implementing a library which makes use of the GSL for matrix operations. I am now at a point where I need to raise things to any power, including imaginary ones. I already have the code in place to handle negative powers of a matrix, but now I need to handle imaginary powers, since all numbers in my library are complex.
Does the GSL have facilities for doing this already, or am I about to enter loop hell trying to create an algorithm for this? I need to be able to raise not only to imaginary but also complex numbers, such as 3+2i. Having limited experience with matrices as a whole, I'm not even certain on the process for doing this by hand, much less with a computer.
Hmm I never thought the electrical engineering classes I went through would help me on here, but what do you know. So the process for raising something to a complex power is not that complex and I believe you could write something fairly easily (I am not too familiar with the library your using, but this should still work with any library that has some basic complex number functions).
First your going to need to change the number to polar coordinates (i.e 3 + 3i would become (3^2 + 3^2) ^(1/2) angle 45 degrees. Pardon the awful notation. If you are confused on the process of changing the numbers over just do some quick googling on converting from cartesian to polar.
So now that you have changed it to polar coordinates you will have some radius r at an angle a. Lets raise it to the nth power now. You will then get r^n * e^(jan).
If you need more examples on this, research the "general power rule for complex numbers." Best of luck. I hope this helps!
Just reread the question and I see you need to raise to complex as well as imaginary. Well complex and imaginary are going to be the same just with one extra step using the exponent rule. This link will quickly explain how to raise something to a complex http://boards.straightdope.com/sdmb/showthread.php?t=261399
One approach would be to compute (if possible) the logarithm of your matrix, multiply that by your (complex) exponent, and then exponentiate.
That is you could have
mat_pow( M, z) = mat_exp( z * mat_log( M));
However mat_log and even mat_exp are tricky.
In case it is still relevant to you, I have extended the capabilities of my package so that now you can raise any diagonalizable matrix to any power (including, in particular, complex powers). The name of the function is 'Matpow', and can be found in package 'powerplus'. Also, this package is for the R language, not C, but perhaps you could do your calculations in R if needed.
Edit: Version 3.0 extends capabilities to (some) non-diagonalizable matrices too.
I hope it helps!

Resources