GLSL - length function - glsl

From the GLSL documentation (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/length.xhtml), the length function "calculate the length of a vector".
But I don't get it, what does "length" mean here ?
For instance:
length(.5); // returns .5
length(1.); // returns 1.
So how and why are you supposed to use this function?

See The OpenGL ES Shading Language
8 Built-in Functions, page 63
When the built-in functions are specified below, where the input arguments (and corresponding output) can be float, vec2, vec3, or vec4, genType is used as the argument.
8.4 Geometric Functions, page 68
float length (genType x)
Returns the length of vector x, i.e.,
This means the result of length(.5) is:
sqrt(0.5 * 0.5) = 0.5
and the result of length(1.) is
sqrt(1.0 * 1.0) = 1.0

The documentation uses 'genType' for generic type and mostly it shows all functions accepting this, meaning that it could be any of the base types.
I don't know why it is not more specific when it clearly says that it's a vector operation.
I think most probably it simply returns the input value if it's a 1-dimensional vector which is just one number and it will calculate the length of 2-,3- dimension vectors properly.
Here the length means the euclidean distance of a vector, not the length or count of the element's it has.

Related

Reshaping Fortran arrays

I have a huge m by 1 array (m is very large) called X which is a result of Fortran matmul operation. My problem is to store this apparently 2D array into an 1D array Y of size m.
I tried with Y = reshape(X, [[2]]) and this result some elements NaN. Can anyone point me to Fortran commands to do it quickly. The elements of X may be zero or non-zero.
The second argument of reshape (or the one with keyword shape=) is the shape of the function's result. In your call, you have requested shape [2].
An array with shape [2] is a rank-1 array with two elements. You want a rank-1 array with m elements:
Y = RESHAPE(X, [m])
Now, in this case there's no need to use reshape:
Y = X(:,1)
where the right-hand side is the rank-1 array section of X.
When you have Y=reshape(X,[2]), if Y is not allocatable and not of size 2 then you have a problem which may indeed result in your compiler deciding---as it is quite entitled to do---to give you a few NaNs.
Note also that you may not need to reshape your array, depending on how you intend to later use it.

GLSL sum of vector vec3 and float

This may be odd because as I understand a vector and a scalar cannot be added. However I've found this sample and in line 157 it doing the following operation:
hsv.x + vec3(0.,2./3.,1./3.)
where hsv.x happens to be a float number, the value comes from the mouse X coordinates and well the rest is a vec3.
My question is what is the result of that operation?
If you add a scalar to a vector, then the scalar will be add to each component of the vector, because the The OpenGL Shading Language specification (Version 4.6, Chapter 5 Operators and Expressions) says:
One operand is a scalar, and the other is a vector or matrix. In this case, the scalar operation is
applied independently to each component of the vector or matrix, resulting in the same size vector
or matrix.

Are functions on matrices applied to the entire matrix or each row in Fortran?

I've never written in Fortran, but I'm trying to adapt a script to R and the following lines are confusing me. So this is how the variable is defined:
real, dimension(n,nd) :: x
Does this mean x is n arrays filled with nd number of real values or a n x nd matrix?
Then
amax = maxval(abs(x))
x = x/amax
is applied. Is the variable amax a global max of the absolute values in x or is it an array of n max values, one for each row? This is important to know if the x = x/amax is being applied to each row or the entire matrix. The purpose of this function seems to be some type of normalization.
The question of the title is much more general than that of the body, so I'll come to that later.
The result of maxval(array) is a scalar, being the maximum value in array (if it's of non-zero size).
In your example, x is a single array of rank 2 (which is commonly thought of as being a matrix). Thus, maxval(x) is indeed what you call the global maximum of that matrix. An alternative form of maxval is required to give the row-by-row maxima: maxval(x,dim=2).
Now, there is something else to note from your example:
x = x/amax
has a requirement about the shapes of x and amax.
You don't give a declaration for amax but there are two possibilities:
amax has the same shape as x; or
amax is a scalar.
[Note that amax needn't be a scalar just because it is assigned a scalar result from that maxval reference. However, you will see that amax won't be declared as rank 1 with size the number of rows of x, so that's another clue that maxval is giving the global maximum.]
These two possibilities come from conformability rules for division. With amax a scalar each element of x is divided by that value; with amax an array each element of x is divided by the corresponding element in amax.
If you want to normalize each individual row of x then you just can't use that division expression with amax a rank 1 array.
Coming to the more general question: even though it's an either/or question the answer is "no". There is no single way. Each function acts as it is defined.
As a general rule, though, the intrinsic functions of Fortran rarely care about the specific case of arrays which have "rows". But one useful thought is that a function acts either:
on all elements individually, returning an array of the same shape;
on the array as a whole, returning a scalar.
Moderated by the fact that many will have this dim argument which causes the function to act on slices instead.
The first line means that the variable x is an array of two dimensions (n,nd) and not n arrays of nd values. The function maxval returns the maximum value in this array.
See page 130 (in the PDF not the printed number) in F90_notes.pdf (you will also find a whole chapter concerning the arrays in the same document).
To add to Baruchel's answer: x/amax divides each element of the 2D array x by the scalar amax.

Fortran - Maxval returns weird results when dimension is specified

I have a 3x2 array and have filled it with the numbers 1-6
so that it looks like
1 4
2 5
3 6
I then call maxval on it, and specify that I wish to find the max value along dimension 1. One would expect that it should return 3, no?
But for some reason my output is '3 6'
PROGRAM maxv
IMPLICIT None
INTEGER, DIMENSION(3,2) :: x
DATA x /1,2,3,4,5,6/
WRITE(*,*) maxval(x,dim=1)
ENDPROGRAM maxv
I used Gfortran 4.6.3 if the issue lies within my compiler
According to http://www.nsc.liu.se/~boein/f77to90/a5.html , maxval when you specify a dimension is supposed to supply the maxval in that dimension.
Or maybe I have overlooked some stuffs.
Yes, you overlooked some stuffs; maxval is behaving correctly.
When you write, for a rank-2 array x
maxval(x,dim=1)
the function returns a rank-1 array with the same number of elements as there are columns in x, each element being the maximum value of the corresponding column in x. Similarly
maxval(x,dim=2)
would, for your example, return the rank-1 array [4,5,6] -- the maximum value in each row of x.
The GNU documentation explains the function better than the source you cite, IBM explain it even better and include an example of the function's use.

Dividing each element in a container between a given number C++

I was multiplying each container against another number so I did the following:
local_it begin = magnitudesBegin;
std::advance(begin , 2);
local_it end = magnitudesBegin;
std::advance(end, 14);
std::transform(begin, end, firstHalf.begin(),
std::bind1st(std::multiplies<double>(),100));
It worked wonders, problem is when doing the same to divide between another container. Here is a working example of my problem:
const std::size_t stabilitySize = 13;
boost::array<double,stabilitySize> secondHalf;
double fundamental = 707;
boost::array<double, stabilitySize> indexes = {{3,4,5,6,7,8,9,10,11,12,13,14,15}};
std::transform(indexes.begin(), indexes.end(), secondHalf.begin(),
std::bind1st(std::divides<double>(),fundamental));
It does divide the container. But instead of dividing each element in the array against 707 it divides 707 between each element in the array.
std::bind1st(std::divides<double>(),fundamental)
The code above takes a functor std::divides<double> that takes two arguments and fixes the value of the first argument to be fundamental. That is it fixes the numerator of the operation and you get the expected result. If you want to bind fundamental to be the denominator, use std::bind2nd.
you can try the following , divide has a completely different operation than multiply, it just divides a constant number by all your elements
std::bind1st(std::multiplies<double>(),1.0/707.0));
If the number 707.0 is something like a fundamental constant, and a division can be seen as a "conversion", let's call it "x to y" (I don't know what your numbers are representing, so replace this by meaningful words). It would be nice to wrap this "x to y" conversion in a free-standing function for re-usability. Then, use this function on std::transform.
double x_to_y(double x) {
return x / 707.0;
}
...
std::transform(..., x_to_y);
If you had C++11 available, or want to use another lambda-library, another option is to write this in-line where being used. You might find this syntax more readable like parameter binding using bind2nd:
std::transform(..., _1 / 707.0); // when using boost::lambda