Centered finite-difference in Scilab - scilab

Problem: Use the following data to find the velocity and acceleration
at t = 10 seconds:
Time, t, s 0 2 4 6 8 10 12 14 16
Position, x, m 0 0.7 1.8 3.4 5.1 6.3 7.3 8.0 8.4
I resolved the centered finite-difference
How can I apply this in Scilab?

This calculates velocity from the given arrays x and t, using central differences:
v = (x(3:$) - x(1:$-2)) ./ (t(3:$) - t(1:$-2))
To see what this does, focus on the first index in each range:
(x(3) - x(1)) ./ (t(3) - t(1))
Clearly, this is the velocity at the 2nd moment of time. The formula performs this calculation for all times when it's possible to do; the centered difference formula does not apply at the first and last moment. One may want to introduce truncated time range to reflect this:
tr = t(2:$-1)
Similarly for acceleration:
a = (x(3:$) - 2*x(2:$-1) + x(1:$-2)) ./ (t(3:$) - t(1:$-2)).^2
This can now be plotted with plot(tr,v) or plot(tr,a). And to look up their values when time is 10, use
v(tr==10)
and
a(tr==10)

Related

Moving average in negative direction (ma in R forecast) [duplicate]

This question already has answers here:
Moving average of previous three values in R
(3 answers)
Closed 2 years ago.
For a series
X=(x_1,x_2,...x_t-2, x_t-1, x_t)
I would like to compute a moving average for each point with respect to the previous k time steps. For example, if k = 2, I want to return:
X =(NA, (x_1+x_2)/2 ... (x_t-2 + x_t-3)/2, (x_t-2 + x_t-1)/2, (x_t + x_t-1)/2)
If I use the moving average function ma, e.g.
ma(X, order = 2, centre = TRUE)
I get the average of each point and its neighbor in the positive and negative direction, while setting centre=FALSE calculates the moving average with respect to the positive direction. Is there a simple way to have point t as the running average of (t-k+1...t)?
Assuming test input X as shown this takes the mean of the current and prior value. Note the r on the end of rollmeanr which tells it to use the right aligned version rather than the center aligned version.
library(zoo)
X <- 1:10 # test input
rollmeanr(X, 2, fill = NA)
## [1] NA 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
so does this (no packages):
n <- length(X)
c(NA, (X[-1] + X[-n])/2)
## [1] NA 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
and this somewhat more general base R approach (also no packages):
k <- 2
c(rep(NA, k-1), rowMeans(embed(X, k)))
## [1] NA 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5

Stupidly simple algebra help for some programming

I'm coding a "wind" thing for a game where if you run a certain wind command, it blows people away in a radius around you.
x is the maximum distance a player can be from the wind source
y is the actual distance a player is from the source of the wind
z is some number between 0 and 10 where if the player is
right next to the wind source z would equal 0 and if
the player is 30 blocks away it would equal 10.
15 blocks away would make z = 5, etc.
x = 30
z = y / x * 10
all this works fine, but I need the z to be opposite. I need z to be 10 when the player is near and 0 when the player is at 30 blocks. 15 blocks away should be 5, etc
My math is failing me on how I can invert these numbers in an easy fashion
Does
z=(1-y/x)*10
work for you?

Minimum edge weight along a path

How would I find the maximum of a set of minimum edge weights along all possibles path between arbitrary vertices (u,v)?
I was thinking a modification of Floyd-Warshall?
i.e. Path 1: s - a - b - c - d - t with weights 1 - 5 - 6 - 10 - 9
Minimum edge weight is 1
Path 2: s - x - y - z - w - t with weights 3 - 9 - 8 - 6 - 7
Minimum edge weight is 3
Thus the result is max(1, 3) = 3
Yes, a modification of Floyd-Warshall would work - instead of shortest path length, you'll keep track of maximum path "width".
If you're only interested in two vertices, you may take a simpler approach: start with an empty graph and add edges ordered by their weight (from high to low). When the nodes in question get connected, the last edge added gives you the maximal "width". Done properly (i.e. using disjoint set to check the connectedness), this will be quicker then Floyd-Warshall.
Note: I'm only considering positive weights.

Finding the opposite of a number in a 0 to 10 scale

This is probably something silly and simple in vectors or something, but I can't figure it out with my remedial Algebra. (Sorry for the initial confusion, I didn't fully explain this as I didn't think the 2nd half of my operation was relevant.)
I have a variable between 0 and 10. I want to find its opposite in that same scale, but I also want to change the "depth" of what that opposite means.
Variables:
X = User input variable between 0-10 (really 0-1.0)
Y = User input Depth between 0-10 (really 0-1.0)
Z = My result I'm looking for.
Example if my depth (Y) is Full (10), X would be:
X=0's opposite would be 10
X=1's opposite would be 9
X=2's opposite would be 8
etc..
Example if my depth (Y) is None (0), X would be:
X=0's opposite would be 0
X=1's opposite would be 1
X=2's opposite would be 2
etc..
I'm trying to accomplish this in Reaktor, a program for designing musical synthesizers. Specifically designing a "depth" parameter on a Chorus effect that inverts the left and right signal delay. So that the "rate" (X in this example) for the left signal is the opposite of the "rate" for the right signal, and the difference of how opposite they are is controlled by the "depth" (Y).
If x is your number, then what you're looking for is simply (10 - x).
edit One functional form that satisfies your updated spec is (x + y - (x * y) / 5.0). This is designed for values of x and y between 0 and 10.
X = 10 - Y where Y is input and X is output
0's opposite is 10: 10 = 10-0
1's opposite is 9: 9 = 10-1
2's opposite is 8: 8 = 10-2

Convert arbitrary length to a value between -1.0 a 1.0?

How can I convert a length into a value in the range -1.0 to 1.0?
Example: my stage is 440px in length and accepts mouse events. I would like to click in the middle of the stage, and rather than an output of X = 220, I'd like it to be X = 0. Similarly, I'd like the real X = 0 to become X = -1.0 and the real X = 440 to become X = 1.0.
I don't have access to the stage, so i can't simply center-register it, which would make this process a lot easier. Also, it's not possible to dynamically change the actual size of my stage, so I'm looking for a formula that will translate the mouse's real X coordinate of the stage to evenly fit within a range from -1 to 1.
-1 + (2/440)*x
where x is the distance
So, to generalize it, if the minimum normalized value is a and the maximum normalized value is b (in your example a = -1.0, b = 1.0 and the maximum possible value is k (in your example k = 440):
a + x*(b-a)/k
where x is >= 0 and <= k
This is essentially two steps:
Center the range on 0, so for example a range from 400 to 800 moves so it's from -200 to 200. Do this by subtracting the center (average) of the min and max of the range
Divide by the absolute value of the range extremes to convert from a -n to n range to a -1 to 1 range. In the -200 to 200 example, you'd divide by 200
Doesn't answer your question, but for future googlers looking for a continuous monotone function that maps all real numbers to (-1, 1), any sigmoid curve will do, such as atan or a logistic curve:
f(x) = atan(x) / (pi/2)
f(x) = 2/(1+e-x) - 1
(x - 220) / 220 = new X
Is that what you're looking for?
You need to shift the origin and normalize the range. So the expression becomes
(XCoordinate - 220) / 220.0
handling arbitrary stage widths (no idea if you've got threads to consider, which might require mutexes or similar depending on your language?)
stageWidth = GetStageWidth(); // which may return 440 in your case
clickedX = MouseInput(); // should be 0 to 440
x = -1.0 + 2.0 * (clickedX / stageWidth); // scale to -1.0 to +1.0
you may also want to limit x to the range [-1,1] here?
if ( x < -1 ) x = -1.0;
if ( x > 1 ) x = 1.0;
or provide some kind of feedback/warning/error if its out of bounds (only if it really matters and simply clipping it to the range [-1,1] isn't good enough).
You have an interval [a,b] that you'd like to map to a new interval [c,d], and a value x in the original coordinates that you'd like to map to y in the new coordinates. Then:
y = c + (x-a)*(c-d)/(b-a)
And for your example with [a,b] = [0,440] and [c,d] = [-1,1], with x=220:
y = -1 + (220-0)*(1 - -1)/(440-0)
= 0
and so forth.
By the way, this works even if x is outside of [a,b]. So as long as you know any two values in both systems, you can convert any value in either direction.

Resources