Define swizzling programmatically (as in GLSL) - swizzling

How would one write swizzling as a defined behaviour in a programming language? (swizzling members like matrices and vectors in GLSL) So if I wanted to make a programming language that would allow the definition of swizzling on some members, what would be a good way to do it? So for example I could do this:
struct
{
swizzable
{
float x, float y, float z, float w
}
}
But this is missing a lot. For example it does not define that what sould it return when I swizzle more or less elements or assign to a subset or just the elements backwards. Like in GLSL I can do v.xyz to create a Vec3 from a Vec4 called v. Or I could assign a subset of members: v.zyx = ... in any order.
So this swizzable substruct is not a solution (or at least too limited). Another way would be to return an array of swizzled members and an implicit cast (with a constructor) would generate the wanted element:
struct Vec2
{
swizzable { float x, float y }
Vec2(float[2] elements)
{ x = elements[0]; y = elements[1]; }
}
struct Vec3
{
swizzable { float x, float y, float z }
}
So if I accessed a Vec3's x and y via swizzling, I would get a float[2] and because I have a constructor for Vec2, I can assign this array to it (and implicitly instantiating a vec2).
This looks like a better solution but still: How could one do better?
Edit: Sorry I didn't specify the question: I want to implement a programming language that supports this kind of thing.

I'm not sure how to give a good, detailed answer, so here is just one idea.
If I understand right, swizzling is mainly a syntactic convenience. The page https://www.opengl.org/wiki/GLSL_Optimizations gives the following example of swizzling:
gl_FragColor = mycolor.xyzw * constantList.xxxy + constantList.yyyx;
This could simply be syntactic shorthand for something like:
gl_FragColor = Vector(mycolor.x, mycolor.y, mycolor.z, mycolor.w)
* Vector(constantList.x, constantList.x, constantList.x, constantList.y)
+ Vector(constantList.y, constantList.y, constantList.y, constantList.x);
So, one step may be to figure out how to parse the shorter syntax and interpret it as meaning something similar to the longer syntax.
I don't see why it would be necessary to declare the struct as anything more complicated than struct myStruct { float x, float y, float z, float w }. The language itself should be able to handle all the details of how to implement this swizzling.

Related

Types with Math.net numerics

I am starting to use the Math.net numerics library and I can't find examples, so I'm running into a few issues:
To make a simple example, I have two arrays of doubles. I want to divide one by the other and then calculate the moving average.
So, the code looks like this:
var VD1 = Vector<double>.Build.Dense(Data1.ToArray());
var VD2 = Vector<double>.Build.Dense(Data2.ToArray());
var R = VD1 / VD2;
var SMA = R.MovingAverage(15);
The problem is that, on the way, the data type changes. It starts as 2 Vectors, the division result is a Vector and the SMA result is not, it's an IEnumerable<double>.
So, now if I want to plug that result into more functions, for example multiply it by another array, I can't. I have to rebuild a Vector from the result.
Am I somehow doing this wrong? I can't imagine that the API would bounce back and forth between different but similar types.
You are doing it right. That is how MathNet is designed. E.g., var R = VD1 / VD2; calls
// Summary: Pointwise divides two Vectors.
public static Vector<T> operator /(Vector<T> dividend, Vector<T> divisor);
and returns Vector<T>.
var SMA = R.MovingAverage(15); calls
public static IEnumerable<double> MovingAverage(this IEnumerable<double> samples, int windowSize);
and returns IEnumerable<double>.
You can call MovingAverage with Vector<double> R, because Vector<double> implements IEnumerable<double> and you get implicit casting. But MovingAverage does not know its argument is Vector<double>, it's designed to return IEnumerable<double>.
And that makes sense. As far as I remember from colledge, moving average is about time series and it has no explicit relationship to vectors.
But you can have some workarounds. For example your own overload for MovingAverage:
static class VectorHeplper
{
public static Vector<double> MovingAverage(this Vector<double> samples, int windowSize)
{
return DenseVector.OfEnumerable(samples.AsEnumerable().MovingAverage(windowSize));
}
}
Then var SMA = R.MovingAverage(15); is Vector<double>.
Anyway, building a new instance of Vector is the right and logical way.

Finding quaternion, representing transformation from one vector to another

Intro.
Previously, I've asked a question on converting rgb triple to quaternion. After that question I've managed to get unit quaternions, but I am in doubt of their internal structure. There was no easy way to operate them, and to separate luma and chroma, since that were quaternions of unit length. According to my feeling about it, luminance should be encoded in the either real part, or a whole magnitude; And color "chroma" information should be encoded in the imaginary part.
Today I've decided to improve things up, taking another approach, different from the first one in the link above. I think it could success, since quaternion could store not only rotation(unit quaternion), but scale as well. First things first, so I'll start with explaining my next idea. I would use GLSL shader syntax in the following explanations.
Approach description and the question body.
For some pixel of an image, let's concieve a 3D vector vec3 u within the unit cube, where positive coordinates are lying in closed range [0.0, 1.0], and are representing full rgb colorspace. So now u's coordinates , u.x, u.y and u.z would represent red, green and blue values of that pixel, accordingly. Then lets take a pure white vector const vec3 v = vec3(1.0, 1.0, 1.0);. And let's define some quaternion q, so that our vector u is the "v, rotated and scaled with quaternion q". In simple words, q must answer the question "How to transform v, in order to get initially conceived color u?". And lets introduce function for that "rotate and scale" operation: vec3 q2c(in vec4 q, in vec3 v). I'll call it "quaternion-to-color" converter.
Writing q2c(q, v) is pretty simple, just as defined: q2c(q, v) == (q*vec4(v, 0.0))*q'. Here, the "*" operator denotes quaternion multiplication; Lets make it a function vec4 qmul(in vec4 q1, in vec4 q2). And "q'" denotes q's conjugate, lets make it vec4 qconj(in vec4 q). Omitting their simple implementation (that you may find in full source), we would come to classic code:
vec4 q2c(in vec4 q, in vec3 v) {
return qmul(qmul(q, vec4(v, 0.0)), qconj(q));
}
So now we have q2c(q,v) function, that converts quaternion q to color, by rotating and scaling some chosen 3D vector v.
The question is How to find that quaternion q?
From a programmer's perspective, the goal is To write reverse function vec4 c2q(in vec3 u, in vec3 v) - a corresponding "color to quaternion" converter.
Please note, that you should not touch q2c(), without a really good reason. E.g, a serious bug in its logic, leading to "impossibility to solve task", and you can proof that.
How could you check, if your answer is correct?
Indeed, the checking method would arise from the fact that you would get initial value, if you will manage to convert forth and back. So the checking condition is For any non-zero length v, u must always be equal to q2c(c2q(u, v), v). v must have non-zero length, because one cannot "scale zero" to get "something".
To easy things up, I've prepared testing program, using shadertoy.com service.
You would require a decent computer, with working internet connection and a web browser with webGL support (I'm using Chrome). Program should work on any GPU, even embedded into intel's processors. It even worked on my lower-end smartphone!
To test your answer, you should put your proposed formula, written in GLSL syntax, inside c2q() function. Then press apply button, and your changes will come into effect:
Image at the left represents some unchanged source pixels. And right half will contain pixels, transformed forth and back by q2c(c2q()). Obviously, halves must be visually equal, you should not notice any vertical line. An some little mathematical(unnoticeable) error may arise, but only due to floating point's nature - its finite precision and possible rounding errors.
Feel free to edit and experiment, changes will be done only locally, on your computer, and you cannot wreck anything. If video is not playing on first open (shadertoy bug) - try to pause/unpause it. Enjoy!
Hall of c2q() Attempts
If everything is correct, the right side of image(processed one) should be equal to the left side(original). And here I would review different results, that were obtained by putting something instead of xxxxx, in the c2q() implementation:
vec4 c2q(vec3 u, vec3 v) {
return xxxxx;
}
Lets proceed!
Initially I've thought that must just work:
vec4(cross(u, v), dot(u, v)):
One of SE answers:
vec4( cross(u, v), sqrt( dot(u, u) * dot(v, v) ) + dot(u, v) ):
And with his hint "Don't forget to normalize q":
normalize(vec4( cross(u, v), sqrt( dot(u, u) * dot(v, v) ) + dot(u, v) )):
#minorlogic's comment, seems to be a step closer:
scale all q's components by sqrt( length(v)/length(u) ),
vec4(cross(u, v), dot(u, v)) * sqrt( length(u)/length(v) ):
With ratio swapped:
vec4(cross(u, v), dot(u, v)) * sqrt( length(v)/length(u) ):
My attempt:
vec4 c2q(vec3 u, vec3 v) {
float norm_q = sqrt(length(u) / length(v));
vec4 u4 = vec4(normalize(u), 0.0);
vec4 v4 = vec4(normalize(v), 0.0);
return norm_q * (qmul(u4, v4 + u4) / length(v4 + u4));
}

Haskell evaluating properties of a data type only once when first accessed?

In imperative/object oriented programming with mutable state, it would be very common and useful to declare a structure such as the following:
struct RigidBody {
float m_mass;
float m_inverseMass;
Mat3 m_localInverseInertiaTensor;
Mat3 m_globalInverseInertiaTensor;
Vec3 m_globalCentroid;
Vec3 m_localCentroid;
Vec3 m_position;
Mat3 m_orientation;
Vec3 m_linearVelocity;
Vec3 m_angularVelocity;
};
Source: http://allenchou.net/2013/12/game-physics-motion-dynamics-implementations/
There are many properties here that are able to be computed directly from others, such as m_inverseMass from m_mass. In a stateless programming language like Haskell, getting derived values is easy enough:
data RigidBody = RigidBody {mass :: Float}
inverseMass :: RigidBody -> Float
inverseMass body = 1 / mass body
But this computes the inverseMass every time we need it, which can get expensive especially in domains where performance is critical, like physics simulation. I've considered memoization, but I wasn't sure if this is a good way of expressing this lazy evaluation of dependent properties, as it seemed to be a complicated solution. How would I store derivative values without having to recompute them?
As #4castle and #Shersh note, a simple approach would be to include the derived value in the data type:
data RigidBody = RigidBody
{ m_mass :: Float
, m_inverseMass :: Float }
and then use a smart constructor to make new RigidBodys:
rigidBody mass = RigidBody mass (1/mass)
The expression 1/mass will create a thunk for m_inverseMass which, after it is first evaluated, will be available without recalculation, so it provides a sort of auto memoization.
More general transformations, like changing the position and properly updating all the global* fields based on the local* values would be handled in a similar manner. As a simplified example:
module Rigid where
type Vec3 = Double -- just to type check
data RigidBody = RigidBody
{ m_mass :: Float
, m_inverseMass :: Float
, m_pos :: Vec3
, m_localCentroid :: Vec3
, m_globalCentroid :: Vec3
}
rigidBody mass pos centroid =
RigidBody mass (1/mass) pos centroid (centroid + pos)
move body delta =
rigidBody (m_mass body)
(m_pos body + delta)
(m_localCentroid body)
In an application that's performance critical, you would want to take steps to introduce strictness in appropriate places so you don't build up huge piles of unevaluated thunks.
You can store inverseMass as Maybe Float inside RigidBody. When inverseMass is Just someMass you just extract this value. If it's Nothing you compute it and store inside RigidBody. The problem is with this store part. Because as you may know objects are immutable in Haskell.
Naive but simple solution would be to return RigidBody after every computation like this:
data RigidBody = RigidBody
{ rigidBodyMass :: Float
, rigidBodyInverseMass :: Maybe Float }
inverseMass :: RigidBody -> (Float, RigidBody)
inverseMass b#(RigidBody _ (Just inv)) = (inv, b)
inverseMass (RigidBody mass Nothing) = let inv = 1 / mass
in (inv, RigidBody mass (Just inv))
If you have a lot of such fields you may find such approach extremely tedious. And it's not very convenient to write code using such functions. So here is the place where State monad becomes handy. State monad can just keep current RigidBody inside explicit state and update it accordingly through all you stateful computation. Like this:
inverseMass :: State RigidBody Float
inverseMass = do
RigitBody inv maybeInverse <- get
case maybeInverse of
Just inv -> pure inv
Nothing -> do
let inv = 1 / mass
put $ RigidBody mass (Just inv)
pure inv
Later you can just use inverseMass multiple times and only during your first call inverse of mass will be calculated.
You see, in imperative programming languages like C++ state is explicit. You want to update fields of RigidBody. So basically you have some object of type RigidBody which stores some states. Because state is implicit you don't need to specify in your functions that they change fields of RigidBody. In Haskell (and every good programming language) you specify explicitly what is your state and how you will change it. You specify explicitly what objects you want to work with. inverseMass monadic action (or just function if you want) will update your explicit state depending on the current state at the moment of calling this function. This is more or less idiomatic approach in Haskell for such sort of tasks.
Well, another idiomatic solution: just create values of your data type with all fields set to some function calls. Because Haskell is lazy such fields are calculated first time only when they are needed.

Comparison of two floats in Rust to arbitrary level of precision

How can I do a comparison at an arbitrary level of precision such that I can see that two numbers are the same? In Python, I would use a function like round(), so I am looking for something equivalent in Rust.
For example I have:
let x = 1.45555454;
let y = 1.45556766;
In my case, they are similar up to 2 decimal places. So x and y would become 1.46 for the purposes of comparison. I could format these, but that surely is slow, what is the best Rust method to check equivalence, so:
if x == y { // called when we match to 2 decimal places}
To further elucidate the problem and give some context. This is really for dollars and cents accuracy. So normally in python would use the round() function with all its problems. Yes I am aware of the limitations of floating point representations. There are two functions that compute amounts, I compute in dollars and need to handle the cents part to the nearest penny.
The reason to ask the community is that I suspect that if I roll my own, it could hit performance and it's this aspect - which is I why I'm employing Rust, so here I am. Plus I saw something called round() in the Rust documentation, but it seems to take zero parameters unlike pythons version.
From the Python documentation:
Note The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.
For more information, check out What Every Programmer Should Know About Floating-Point Arithmetic.
If you don't understand how computers treat floating points, don't use this code. If you know what trouble you are getting yourself into:
fn approx_equal(a: f64, b: f64, decimal_places: u8) -> bool {
let factor = 10.0f64.powi(decimal_places as i32);
let a = (a * factor).trunc();
let b = (b * factor).trunc();
a == b
}
fn main() {
assert!( approx_equal(1.234, 1.235, 1));
assert!( approx_equal(1.234, 1.235, 2));
assert!(!approx_equal(1.234, 1.235, 3));
}
A non-exhaustive list of things that are known (or likely) to be broken with this code:
Sufficiently large floating point numbers and/or number of decimal points
Denormalized numbers
NaN
Infinities
Values near zero (approx_equal(0.09, -0.09, 1))
A potential alternative is to use either a fixed-point or arbitrary-precision type, either of which are going to be slower but more logically consistent to the majority of humans.
This one seems to work pretty well for me.
fn approx_equal (a: f64, b: f64, dp: u8) -> bool {
let p = 10f64.powi(-(dp as i32));
(a-b).abs() < p
}

Optimizing parameter input for functions

I have a function that has a large number if individual input parameters, the function is also run hundreds of millions of times during the program.
If i wanted to optimize this function, should I create a new data structure that holds all the input parameters and pass it to the function by reference instead of passing each parameter individually to the function? Or would it not matter because the compiler is smart enough to deal wit this in an even more efficient manner?
In general, it's much better to pass a data structure that contains your variables. This isn't pretty to look at or use:
void f(int a, int b, int c, int d, int e, int f)
{
// do stuff
}
This is much nicer:
void f(Params p)
{
// do stuff with p
}
You may want to do pass by reference, so the compiler can just pass a reference to the object, and not copy the entire data structure.
As a real example:
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
{
double dx = x1 - x2;
double dy = y1 - y2;
double dz = z1 - z2;
return sqrt(dx*dx + dy*dy + dz*dz);
}
It would be better if encapsulated our (x, y, z) into a data structure though:
struct Point
{
double x;
double y;
double z;
};
double distance(const Point &p1, const Point &p2)
{
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
double dz = p1.z - p2.z;
return sqrt(dx*dx + dy*dy + dz*dz);
}
Much cleaner code, and you get the added bonus that it could* perform better (*Depending on how smart your compiler is at optimizing either version).
Obviously this could vary wildly depending on what you're actually trying to accomplish, but if you have several (4+) variables that have a similar usage in a certain context, it may be better to just pass it in a data structure.
Are the arguments mostly constant, or do most of them change on every call? You don't want to evaluate arguments many times if you could only do them once.
Keep in mind what the compiler does with arguments.
It evaluates each one and pushes it on the stack. Then the function is entered, and it refers to those arguments by their offset in the stack. So it is basically the same as if you put the arguments into a block and passed the block. However, if you build the block yourself, you may be able to re-use old values and only evaluate the ones you know have changed.
In any case, you really have to look at how much work goes on inside the function relative to the time spent passing arguments to it. It's irrelevant that you're calling it 10^8 times without knowing over what overall time span. That could be 10ns per call, or 10ms per call. If the latter, nearly all the time is spent inside the function, so it probably doesn't make much difference how you call it.

Resources