In C++11 I want to calculate the partial sum of a vector using std::partial_sum.
std::vector<double> vec = {-1.0, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1};
std::partial_sum(vec.begin(), vec.end(), vec.begin());
Unfortunatelly, the last entry of the resulting vector is 1.38778E-16 due to rounding errors of doubles and the fact that 0.1 has no exact presentaion as double.
vec = {-1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 1.38778E-16};
Is there any chance to use the Kahan algorithm in std::partial_sum to reduce rounding errors and get a smaller error - something like
std::partial_sum(vec.begin(), vec.end(), vec.begin(), KahanSum);
You can implement Kahan summation on top of std::partial_sum (based on Wikipedia pseudocode):
double c = 0.0;
std::partial_sum(vec.begin(), vec.end(), vec.begin(),
[c](double sum, double elem) mutable -> double {
double y = elem - c;
double t = sum + y;
c = (t - sum) - y;
return t;
});
This still won't get you zero though, since (double)0.1 is exactly equal to
0.1000000000000000055511151231257827021181583404541015625 and so the exact sum of your array is about 5.5511151231E-17 (assuming standard double).
Related
I’m trying to make 6 dots along a line(0, random(height), width, random(height)). The dots should be evenly spaced.
You can use lerp(start, end, t) to linearly interpolate between to values by specifying t: where in between the start/end values you'd like the result to be.
This t value is between 0.0 and 1.0 (normalised value). You can think if of it as percentage. (e.g. 0.0 is at the start (0%) value, 1.0 is at the end value(100%), 0.5 is 50% between the start and end value).
In your case, you would:
store the randomly generated values first (before interpolation)
iterate 6 times, and for each iteration
for each iteration, map the iteration index to the normalised value (t)
Finally, use lerp() by plugging in the from/to values and the t value at the current iteration.
Here's a basic example:
float fromX = 0;
float fromY = random(height);
float toX = width;
float toY = random(height);
int numPoints = 6;
for(int i = 0 ; i < numPoints; i++){
float interpolationAmount = map(i, 0, numPoints - 1, 0.0, 1.0);
float interpolatedX = lerp(fromX, toX, interpolationAmount);
float interpolatedY = lerp(fromY, toY, interpolationAmount);
ellipse(interpolatedX, interpolatedY, 9, 9);
}
Alternatively you can use PVector's lerp() to easiely interpolate between points in 2D (or 3D), without having to interpolate every component:
PVector start = new PVector(0 , random(height));
PVector end = new PVector(width, random(height));
for(float t = 0.0 ; t <= 1.0 ; t += 1.0 / 5){
PVector inbetween = PVector.lerp(start, end, t);
ellipse(inbetween.x, inbetween.y, 9, 9);
}
Update
The slope is the ratio (division) between the difference on Y axis (called rise, Δy = y2 - y1 (E.g. toY - fromY)) and the difference on the X axis (called run, Δx = x2 - x1 (e.g. toX - fromY)).
You can use this difference between start and end points (defining the slope) to draw the points in between.
If you divide this difference into equal sections, each for a point you'd like to draw, then you can multiply it as you iterate and simply translate/offset it from the start position:
// start point
float fromX = 0;
float fromY = random(height);
// end point
float toX = width;
float toY = random(height);
// difference between each component
float diffY = toY - fromY;
float diffX = toX - fromX;
// slope = ratio between Y and X difference
float slope = diffY / diffX;
println("slope as ratio", slope, "as degrees", degrees(atan2(diffY, diffX) + PI));
// start drawing 6 points
int numPoints = 6;
// precalculate a sixth
float sectionIncrement = 1.0 / (numPoints - 1);
for(int i = 0 ; i < 6; i++){
// a sixth incremented (e.g. 1/6 * 0, * 1, *2, ...)
float section = sectionIncrement * i;
// a sixth incremented and mulitplied to the difference
// e.g. 1/6 of slope difference, 2/6 of slope / etc.
// to which we offset the start location (fromX, fromY +)
float x = fromX + (diffX * section);
float y = fromY + (diffY * section);
// render
ellipse(x, y, 9, 9);
}
point(0, random(height))
point(width/5, random(height))
point(width/5*2, random(height))
point(width/5*3, random(height))
point(width/5*4, random(height))
point(width, random(height))
I have a simple function that takes a float parameter x in the range [-1.0, 2.0] and maps it to range [0.0, 1.0] such that values below 0.0 are mapped to 1.0 and values above 1.0 are mapped to 0.0:
float wrap_ternary(x) {
// result is between [0.0, 1.0]
return x < 0.0 ? x + 1.0 : x > 1.0 ? x - 1.0 : x;
}
I want to convert that function to use math expressions instead of conditionals. I've come up with the following algorithm:
float wrap_mod(x) {
return (((x + 1.0) % 2.0 + 1.0) % 1.0);
}
However the edge wrapping of this algorithm is inclusive i.e. 1.0/2.0 are mapped to 0.0 whereas the ternary version would map these values to 1.0:
X
wrap_ternary
wrap_mod
wrong
-1.0
0.0
0.0
-0.5
0.5
0.5
0.0
0.0
0.0
0.5
0.5
0.5
1.0
1.0
0.0
x
1.5
0.5
0.5
2.0
1.0
0.0
x
How would I modify my algorithm so that it produces the same results as the ternary version? I've tried to subtract EPSILON from my modulo but that didn't really work... I just can't wrap my head around this. No pun intended.
I am not familiar with GLSL, but it seems to be quite similar to C. So below is a C solution wrap_floor() that uses the floor() function to implement the conditional addition or subtraction, together with a test framework that tests it exhaustively.
The only issue is getting the switchover points correct, which would naturally fall on integers. The question already mentions "epsilon techniques" in which one increases or diminishes floating-point numbers by one ulp (unit in the last place) and which can be used to shift the bounds slightly. To get the correct shift for this case, we need to multiply the input by the "magic" multiplier (1 - 1 ulp). Assuming that float maps to the IEEE-754 binary32 format, the desired number is the literal float constant 0.99999994.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// result is between [0.0, 1.0]
float wrap_ternary (float x) {
return x < 0.0 ? x + 1.0 : x > 1.0 ? x - 1.0 : x;
}
float wrap_floor (float x) { return x - floorf (x * 0.99999994f); }
int main (void)
{
/* exhaustive test of wrapping functions over [-1,2] */
float x = -0.0f;
while (x >= -1.0f) {
if (wrap_ternary (x) != wrap_floor (x)) {
printf ("x=% .9e wrap_ternary = % .8e wrap_floor=% .8e\n",
x, wrap_ternary (x), wrap_floor (x));
}
x = nextafterf (x, -INFINITY);
}
x = 0.0f;
while (x <= 2.0f) {
if (wrap_ternary (x) != wrap_floor (x)) {
printf ("x=% .8ef wrap_ternary = % .8e wrap_floor=% .8e\n",
x, wrap_ternary (x), wrap_floor (x));
}
x = nextafterf (x, INFINITY);
}
return EXIT_SUCCESS;
}
This might work as expected, though...
float wrap_somehow(x) {
return 0.5 - (frac(1.5 - abs(x - 0.5)) - 0.5) * sign(x - 0.5);
}
The frac function, which returns the fractional part of a float, seems to have the behaviour you want for all inputs other than 1.0 and 2.0. So this would work:
float wrap_ternary(x) {
return (x == 1.0 || x == 2.0) ? 1.0 : frac(x);
}
I would like to know how to simply reverse the color order of a given colormap in order to use it with plot_surface.
The standard colormaps also all have reversed versions. They have the same names with _r tacked on to the end. (Documentation here.)
The solution is pretty straightforward. Suppose you want to use the "autumn" colormap scheme. The standard version:
cmap = matplotlib.cm.autumn
To reverse the colormap color spectrum, use get_cmap() function and append '_r' to the colormap title like this:
cmap_reversed = matplotlib.cm.get_cmap('autumn_r')
In matplotlib a color map isn't a list, but it contains the list of its colors as colormap.colors. And the module matplotlib.colors provides a function ListedColormap() to generate a color map from a list. So you can reverse any color map by doing
colormap_r = ListedColormap(colormap.colors[::-1])
As of Matplotlib 2.0, there is a reversed() method for ListedColormap and LinearSegmentedColorMap objects, so you can just do
cmap_reversed = cmap.reversed()
Here is the documentation.
As a LinearSegmentedColormaps is based on a dictionary of red, green and blue, it's necessary to reverse each item:
import matplotlib.pyplot as plt
import matplotlib as mpl
def reverse_colourmap(cmap, name = 'my_cmap_r'):
"""
In:
cmap, name
Out:
my_cmap_r
Explanation:
t[0] goes from 0 to 1
row i: x y0 y1 -> t[0] t[1] t[2]
/
/
row i+1: x y0 y1 -> t[n] t[1] t[2]
so the inverse should do the same:
row i+1: x y1 y0 -> 1-t[0] t[2] t[1]
/
/
row i: x y1 y0 -> 1-t[n] t[2] t[1]
"""
reverse = []
k = []
for key in cmap._segmentdata:
k.append(key)
channel = cmap._segmentdata[key]
data = []
for t in channel:
data.append((1-t[0],t[2],t[1]))
reverse.append(sorted(data))
LinearL = dict(zip(k,reverse))
my_cmap_r = mpl.colors.LinearSegmentedColormap(name, LinearL)
return my_cmap_r
See that it works:
my_cmap
<matplotlib.colors.LinearSegmentedColormap at 0xd5a0518>
my_cmap_r = reverse_colourmap(my_cmap)
fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = my_cmap, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = my_cmap_r, norm=norm, orientation='horizontal')
EDIT
I don't get the comment of user3445587. It works fine on the rainbow colormap:
cmap = mpl.cm.jet
cmap_r = reverse_colourmap(cmap)
fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = cmap, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = cmap_r, norm=norm, orientation='horizontal')
But it especially works nice for custom declared colormaps, as there is not a default _r for custom declared colormaps. Following example taken from http://matplotlib.org/examples/pylab_examples/custom_cmap.html:
cdict1 = {'red': ((0.0, 0.0, 0.0),
(0.5, 0.0, 0.1),
(1.0, 1.0, 1.0)),
'green': ((0.0, 0.0, 0.0),
(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 1.0),
(0.5, 0.1, 0.0),
(1.0, 0.0, 0.0))
}
blue_red1 = mpl.colors.LinearSegmentedColormap('BlueRed1', cdict1)
blue_red1_r = reverse_colourmap(blue_red1)
fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = blue_red1, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = blue_red1_r, norm=norm, orientation='horizontal')
There is no built-in way (yet) of reversing arbitrary colormaps, but one simple solution is to actually not modify the colorbar but to create an inverting Normalize object:
from matplotlib.colors import Normalize
class InvertedNormalize(Normalize):
def __call__(self, *args, **kwargs):
return 1 - super(InvertedNormalize, self).__call__(*args, **kwargs)
You can then use this with plot_surface and other Matplotlib plotting functions by doing e.g.
inverted_norm = InvertedNormalize(vmin=10, vmax=100)
ax.plot_surface(..., cmap=<your colormap>, norm=inverted_norm)
This will work with any Matplotlib colormap.
There are two types of LinearSegmentedColormaps. In some, the _segmentdata is given explicitly, e.g., for jet:
>>> cm.jet._segmentdata
{'blue': ((0.0, 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65, 0, 0), (1, 0, 0)), 'red': ((0.0, 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1), (1, 0.5, 0.5)), 'green': ((0.0, 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 1), (0.91, 0, 0), (1, 0, 0))}
For rainbow, _segmentdata is given as follows:
>>> cm.rainbow._segmentdata
{'blue': <function <lambda> at 0x7fac32ac2b70>, 'red': <function <lambda> at 0x7fac32ac7840>, 'green': <function <lambda> at 0x7fac32ac2d08>}
We can find the functions in the source of matplotlib, where they are given as
_rainbow_data = {
'red': gfunc[33], # 33: lambda x: np.abs(2 * x - 0.5),
'green': gfunc[13], # 13: lambda x: np.sin(x * np.pi),
'blue': gfunc[10], # 10: lambda x: np.cos(x * np.pi / 2)
}
Everything you want is already done in matplotlib, just call cm.revcmap, which reverses both types of segmentdata, so
cm.revcmap(cm.rainbow._segmentdata)
should do the job - you can simply create a new LinearSegmentData from that. In revcmap, the reversal of function based SegmentData is done with
def _reverser(f):
def freversed(x):
return f(1 - x)
return freversed
while the other lists are reversed as usual
valnew = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(val)]
So actually the whole thing you want, is
def reverse_colourmap(cmap, name = 'my_cmap_r'):
return mpl.colors.LinearSegmentedColormap(name, cm.revcmap(cmap._segmentdata))
I'm trying to understand the rotation of the matrices using WebGL.
I got this mat4() matrix and I have to apply these transformations :
m = translate(torsoHeight+1*headHeight, 5, 0.0);
m = mult(m, rotate(theta[head1Id], 1, 0, 0))
m = mult(m, rotate(theta[head2Id], 0, 1, 0));
m = mult(m, translate(0.0, -0.5*headHeight, 0.0));
figure[headId] = createNode( m, head, leftUpperArmId, null);
break;
I did not understand exactly how the mult function works. The first parameter is my matrix.
The theta[] is built in this way :
var theta = [0, 0, 0, 0, 0, 0, 180, 0, 180, 0, 0];
and
var headId = 1;
var head1Id = 1;
var head2Id = 10;
Am I right if I thought that the second parameter is another matrix build with the rotate() function ? In this case how does the rotate function work ?
rotate and translate are functions that create matrices.
rotate looks like it's arguments are (angle, vectorx, vectory, vectorz) to create a matrix rotating points around the given vectory.
mult is the standard mathematical multiplication for 4x4 matrices.
You probably should dig in linear algebra tutorials such as https://open.gl/transformations
I have a data set that ranges from 1 to 30,000
I want to normalize it, so that it becomes 0.1 to 10
What is the best method/function to do that?
Would greatly appreciate it if you could give some sample code!
Here's a code snippet, assuming you want a linear normalization. It's a very simplistic version (just straight code, no methods), so you can see "how it works" and can apply it to anything.
xmin = 1.0
xmax = 30000.0
ymin = 0.1
ymax = 10.0
xrange = xmax-xmin
yrange = ymax-ymin
y = ymin + (x-xmin) * (yrange / xrange)
And here it is done as a function:
def normalise(x, xmin, xmax, ymin, ymax)
xrange = xmax - xmin
yrange = ymax - ymin
ymin + (x - xmin) * (yrange.to_f / xrange)
end
puts normalise(2000, 1, 30000, 0.1, 10)
(Note: the to_f ensures we don't fall into the black hole of integer division)
This is a well known way to scale a collection numbers. It has more precise name but I can't remember and fail to google it.
def scale(numbers, min, max)
current_min = numbers.min
current_max = numbers.max
numbers.map {|n| min + (n - current_min) * (max - min) / (current_max - current_min)}
end
dataset = [1,30000,15000,200,3000]
result = scale(dataset, 0.1, 10.0)
=> [0.1, 10.0, 5.04983499449982, 0.165672189072969, 1.08970299009967]
scale(result, 1, 30000)
=> [1.0, 30000.000000000004, 15000.0, 199.99999999999997, 3000.0000000000005]
As you can see, you have to be aware of rounding issues. You should probably also make sure that you don't get integers as min & max because integer division will damage the result.
Here's the Ruby Way for the common case of setting an array's min to 0.0 and max to 1.0.
class Array
def normalize!
xMin,xMax = self.minmax
dx = (xMax-xMin).to_f
self.map! {|x| (x-xMin) / dx }
end
end
a = [3.0, 6.0, 3.1416]
a.normalize!
=> [0.0, 1.0, 0.047199999999999985]
For a min and max other than 0 and 1, add arguments to normalize! in the manner of Elfstrom's answer.
x = x / 3030.3031 + 0.1