OK, lets start:
"segments" is a function which takes a list of points (n x 2 matrix) and creates a vector consisting of the cumulated lengths of the various line segments with 0 as the first entry. This is achieved using Mathcads ability to work with vectors directly. Transposing the "list" matrix is necessary because MC15 does not offer a way to select a specific row of a matrix, we only have a column selector. Now I go throw the transposed list, chose two consecutive points (=columns) and let Mathcad calculate the distance between those points. The total length calculated so far (R[i-1) is added and the result is the next cumulated valued.
So the last value in the return vector is the lenght of the whole curve, the third value in the returned list is the length up to the third point, etc.
"absc2" (you should definitely use other names) calculates now the x-values for a given curve length "d" so it can be compared to the values of "absc" created using the integral and the solve block.
First I find the the largest value in the list "s" of cumulated segment lengths which is still smaller than d. So we know which segment we should have a close look to. In the next segment kind of reverse linear interpolation is used to find the delta_x value we have to add to the x-value of the end of the previous segment to get the value we are looking for. Basically just a matter of an equation of ratios.
"deriv" is working similar, but directly returns the derivative. This is easier to accomplish, as the derivative simply is the slope of the segment we found.
"deriv2" has the additional feature that for curve lengths values which lead in the area (10^-3) around a given point (excluding first and last point) the slope of the two line segments is averaged instead of returning just one of them.
The difference can hardly be seen unless you zoom in and you have to decide whether its worth the effort or not.
One additional idea: If its mandatory for the derivative to be smooth or at least stepless, I guess we could create a deriv3 where the result would be a weighted average of the two nearest slopes. Only if we are exactly in the center of a line segment, the slope of just this segment would be returned.
Hi Werner,
Many thanks for the explanation ! But unfortunately I still didn't understand it XD
Could you please explain the first part of your code line by line ? For example
O <- ORIGIN
Is this an inbuilt command in mathcad ? What does it mean ?
Ro <- 0
Does this mean distance of first point from origin is 0 ? Why use O instead of 0 (zero) ?
for i belongs to .... why use O+1 instead of just 1 ?
The part where you calculated distances between the points using "vector algebra" is awesome ! I just realized |a| could also give the length of the vector (I thought it's only for absolute value of numbers). Is this method faster than the cartesian one (sqrt(x2-x1)^2 +(y2-y1)^2) ?
Sorry for the bother I really hope you don't mind.
Warm Regards,
Aravind.
@adnn wrote:
Hi Werner,
Many thanks for the explanation ! But unfortunately I still didn't understand it XD
Could you please explain the first part of your code line by line ? For example
Unfortunately we cannot simply copy and paste picture in our posts here in this forum. It looks good when editing the post, but gets damaged when pressing the "Post" button. You must save the pic to a file and insert this file via the "Photos" icon - quite cumbersome, I know.
O <- ORIGINIs this an inbuilt command in mathcad ? What does it mean ?
ORIGIN is a system variable you can change either like a normal variable in the sheet or via the menu "->Tools->Worksheet Options->Built-In Variables".
By default numbering in vectors and matrices start by 0 and by changing the variable ORIGIN you may change this. Personally I prefer the default but some prefer to start the indexing at 1. When I write utiity functions most of the time I like to make them ORIGIN indepedent so they would work the same whatever the value of ORIGIN is.
But because ORIGIN is a 6-letter word I define a variable O in my programs and use this instead of ORIGIN (it also reminds me on 0(zero), the value I am used for ORIGIN).
Ro <- 0Does this mean distance of first point from origin is 0 ? Why use O instead of 0 (zero) ?
Yes, this creates a vector with just one element, 0. Its the fictive length of the non-existing "line segment" before the first one. In the absc2 function I use s[i-1 and if i=1 this refers to the element 0 in the segment list which hast to be present and has to be zero for the function to work.
The reason I use O instead of 0 is, as explained above, the attempt to make the function ORIGIN-independent. If you set the ORIGIN to a value different than 0 (lets say 1) the function will still work. If I hard code a zero as index, you would get an error if ORIGIN=1 because there is no index 0 in this case.
The same goes for O+1 and not just 1. It only matters if ORIGIN is not set to zero. O+1 denotes the second possible index.
If you use those functions in sheets with ORIGIN=0 only, you may delete all definitions of O and replace all occurrences of O by 0 without running into problems.
The part where you calculated distances between the points using "vector algebra" is awesome ! I just realized |a| could also give the length of the vector (I thought it's only for absolute value of numbers). Is this method faster than the cartesian one (sqrt(x2-x1)^2 +(y2-y1)^2) ?
Yes, |a| can mean absolute value of a scalar, absolute value of a vector or even the determinant of a square matrix. Especially in the latter case Mathcad often can not determine correctly what you mean and so you have the option to chose between "Absolute Value" and "Square Matrix Determinant" if you right click the absolute sign.
I used the absolute of vectors because its shorter and much more convenient. I had also expected this built-in command to be a bit faster than using squares and root. But as you asked I gave it a try and, alas, squares and roots are faster as you can see in the screenshot below - surprise!
BTW, in the meantime I added a third "deriv" function which works faster and gives a smooth result thanks to linear interpolation:
I gave the sheet you posted at last a try and copied the data from your trial sheet. It still is not working as of a couple of undefined variables.