I know Eigen use Matrix to represent vector, but for templatrized vector, what I know is to use something like
Eigen::Matrix<T,3,1> v;
Is there something like
Eigen::Vector<T,3> for use?
All Eigen::Vector types are mere typedefs. All C++ standards prior to C++11 don't support templated typedefs (aka alias) and Eigen is written to support also older standards than C++11.
If you are using C++11 you can define your own templated Vector alias
template <typename Type, int Size> using Vector = Eigen::Matrix<Type, Size, 1>;
and then use it the way you want
Vector<double, 10> vec;
By the way, Eigen has typedefs for vector sizes between 2 and 4, i.e. Eigen::Vector2d, ..., EigenVector4d. The same typedefs exists for floats with the suffix f and integer i and for complex numbers cd, cf.
Related
coming from python I have a hard time understanding the data structure types and their declaration in c++.
To declare and populate a multidimensional array in python you just do as an example:
arr = [[],[]]
for i in range(2):
arr[i].append(1)
What would be the equivalent in C++? Do I have to use vectors or arrays?
Cheers
Arrays in C/C++ are compile-time fixed size data structures. You declare them by
<data type> <variable name> <dimensions>;
<data type> can be anything you want.
<variable name> is also obvious.
<dimensions> need to be compile-time constants but can be as many as your target hardware supports, syntax is like [5] or [3][2].
You declare an array like
int numbers[5];
or
double weights[3][2];
Then, there are the containers from STL in C++. std::vector<T> behaves like a dynamically sized array, its counterpart the std::array<T> is a compile time array just like the one mentioned above but with container semantics which are a super set of plain arrays.
A multidimensional vector would be declared like
std::vector<std::vector<int>> v;
This just declares a variable and initializes it - a two dimensional array to be precise - and you can later on resize it according to your needs.
Also note that vector will allow you to actually have jagged-arrays rather than the rectangular ones plain arrays always enforce. That is because you can push different sized vector to your v as elements.
You should read more about data structures, containers and algorithms in C++. C++ reference is a very good reference site. c++ page itself has many good pointers.
I'm extracting C struct layout from and executable using gdb-python.
I manage to get all the fields, offsets, types & sizes.
Still, when trying to re-generate the struct's code, I do not have any indication for whether it was marked with GCC's attribute((__packed__)).
Is there any way to get this information from the executable? (preferably using gdb-python, but any other way will do too)
Is there any way to get this information from the executable?
No, but you should be able to deduce this with a simple heuristic:
if sizeof(struct foo) is greater than the sum of its member field sizes, the struct is not packed.
if sizeof(struct foo) is equal to the sum of its member field sizes, the struct is either packed, or its members are naturally aligned with no holes, and packing doesn't matter for it.
There seems to be an extremely limited amount of things you can do with integers in GLSL ES 2.0.
For example:
No bitwise operations are supported.
No intrinsic functions seems to accept int types
So, it seems the only thing you can really do with integers is:
Assign integer to integer
Access array element by index
Basic arithmetic (-, +, *, /), but only between other integers. No operator exists which allows you to add a float and int together.
Compare them between each other.
Convert them to other types
vec constructors allow you to pass integers
Is that really it? Are there any intrinsic functions that take int parameters other than vec constructors? Are there any operations you can do between float and int?
You are correct, use cases of integers are limited. Per OpenGL ES Shading Language spec, 4.1.3:
Integers are mainly supported as a programming aid. At the hardware level, real integers would aid efficient implementation of loops and array indices, and referencing texture units. However, there is no requirement that integers in the language map to an integer type in hardware. It is not expected that underlying hardware has full support for a wide range of integer operations. An OpenGL ES Shading Language implementation may convert integers to floats to operate on them. Hence, there is no portable wrapping behavior.
Since there's no guarantee GLSL ES integer type maps to a hardware integer type, it's only useful for compile-time type checking with little to no effect at runtime. All places that require integers are listed in the spec.
I have medium size C99 program which uses long double type (80bit) for floating-point computation. I want to improve precision with new GCC 4.6 extension __float128. As I get, it is a software-emulated 128-bit precision math.
How should I convert my program from classic long double of 80-bit to quad floats of 128 bit with software emulation of full precision?
What need I change? Compiler flags, sources?
My program have reading of full precision values with strtod, doing a lot of different operations on them (like +-*/ sin, cos, exp and other from <math.h>) and printf-ing of them.
PS: despite that float128 is declared only for Fortran (REAL*16), the libquadmath is written in C and it uses float128. I'm unsure will GCC convert operations on float128 to runtime library or not and I'm unsure how to migrate from long double to __float128 in my sources.
PPS: There is a documentation on "C" language gcc mode: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
"GNU C compiler supports ... 128 bit (TFmode) floating types. Support for additional types includes the arithmetic operators: add, subtract, multiply, divide; unary arithmetic operators; relational operators; equality operators ... __float128 types are supported on i386, x86_64"
How should I convert my program from classic long double of 80-bit to quad floats of 128 bit with software emulation of full precision? What need I change? Compiler flags, sources?
You need recent software, GCC version with support of __float128 type (4.6 and newer) and libquadmath (supported only on x86 and x86_64 targets; in IA64 and HPPA with newer GCC). You should add linker flag -lquadmath (the cannot find -lquadmath' will show that you have no libquadmath installed)
Add #include <quadmath.h> header to have macro and function definitions.
You should modify all long double variable definitions to __float128.
Complex variables may be changed to __complex128 type (quadmath.h) or directly with typedef _Complex float __attribute__((mode(TC))) _Complex128;
All simple arithmetic operations are automatically handled by GCC (converted to calls of helper functions like __*tf3()).
If you use any macro like LDBL_*, replace them with FLT128_* (full list http://gcc.gnu.org/onlinedocs/libquadmath/Typedef-and-constants.html#Typedef-and-constants)
If you need some specific constants like pi (M_PI) or e (M_E) with quadruple precision, use predefined constants with q suffix (M_*q), like M_PIq and M_Eq (full list http://gcc.gnu.org/onlinedocs/libquadmath/Typedef-and-constants.html#Typedef-and-constants)
User-defined constants may be written with Q suffix, like 1.3000011111111Q
All math function calls should be replaced with *q versions, like sqrtq(), sinq() (full list http://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-Library-Routines)
Reading quad-float from string should be done with __float128 strtoflt128 (const char *s, char **sp) - http://gcc.gnu.org/onlinedocs/libquadmath/strtoflt128.html#strtoflt128 (Warning, in older libquadmaths there may be some bugs in strtoflt128, do a double check)
Printing the __float128 is done with help of quadmath_snprintf function. On linux distributions with recent glibc the function will be automagically registered by libquadmath to handle Q (may be also q) length modifier of a, A, e, E, f, F, g, G conversion specifiers in all printfs/sprintfs, like it did L for long doubles. Example: printf ("%Qe", 1.2Q), http://gcc.gnu.org/onlinedocs/libquadmath/quadmath_005fsnprintf.html#quadmath_005fsnprintf
You should also know, that since 4.6 Gfortran will use __float128 type for DOUBLE PRECISION, if the option -fdefault-real-8 was given and there were no option -fdefault-double-8. This may be problem, since 128 long double is much slower than standard long double on many platforms due to software computation. (Thanks to post by glennglockwood http://glennklockwood.blogspot.com/2014/02/linux-perf-libquadmath-and-gfortrans.html)
This is my code.
struct Vector
{
float x, y, z, w;
};
typedef struct Vector Vector;
inline void inv(Vector* target)
{
(*target).x = -(*target).x;
(*target).y = -(*target).y;
(*target).z = -(*target).z;
(*target).w = -(*target).w;
}
I'm using GCC for ARM (iPhone). Can this be vectorized?
PS: I'm trying some kind of optimization. Any recommendations are welcome.
Likely not, however you can try using a restrict pointer which will reduce aliasing concerns in the compiler and potentially produce better code.
It depends on how Vector is defined, but it may be possible. If you're looking for auto-vectorization then try Intel's ICC (assuming we're talking about x86 here ?), which does a pretty good job in certain cases (much better than gcc), although it can always be improved upon by explicit vectorization by hand of course, since the programmer knows more about the program than the compiler can every imply from the source code alone.