How do vec attributes/accessors work in wgsl - wgsl

Hi this is a simple question.
I'm trying to read and understand a shader function which makes use of vec3<f32> variable types.
I don't understand what is that .zzzz key for:
var myvar: vec3<f32> = vec3<f32>(1.3, 3.3, 3.3);
myvar.zzzz; // ??
myvar.xy; // ??
I can only understand myvar.x, myvar.y, myvar.z, but what happens when you combine or repeat those keys?
I can't yet find it in the official documentation unfortunately.
Thanks

This is a swizzle, also called convenience letterings in the spec. The spec section 7.7.1 says:
The convenience letterings can be applied in any order, including duplicating letters as needed. The provided number of letters must be between 1 and 4
There are letterings for x, y, z, w and r, g, b, a. (Note, they can not be mixed.)
So zzzz means make a vec4 initialized with the z component in each spot. The xy means make a vec2 initialized with the x and y components.

So, after looking at this example, my best guess is that myvar.zzzz returns a vec4<f32> initialised with the z component of the myvar vector.
So if a_var = vec<f32>(1.0, 2.0, 3.0), then b_var = a_var.zzzz is equal to (3.0, 3.0, 3.0, 3.0)

Related

How do I calculate inner product of two vectors in nalgebra?

From the following
let v = OVector::<f64, U2>::from_column_slice(&[3_f64, 4_f64]);
let x = &v.transpose() * &v; // get the inner product, i.e. <v,v>
I expected x to be a f64 scalar, i.e. x = 25.0.
But actually, I can only obtain x as OMatrix::<f64, Cosnt<1>, Const<1>>.
The case can be even worse in matrix product operations. for example, the following code doesn't work since v^T v is not a scalar.
let m = OMatrix::<f64, U2, U2>::from_element(1.0);
let v = OVector::<f64, U2>::from_column_slice(&[3_f64, 4_f64]);
// not working
let y = &v.transpose() * &v * m; // types conflict
// working
let y = 25.0 * m; // expected to behave like this
What is the correct way to do this?
Usually, in maths, you would identify 1x1 matrices with scalars (because, for some definition of being equivalent, they are equivalent...). When doing this, the dot product of two vectors is exactly the dot product between two matrices, when we see vectors as matrix columns (which are also equivalent for some equivalence...).
However, here, it is not the case: Rust has to know what is the type of the data. So, I would suggest, since you are using matrices to start with, to use the actual matrix dot product, not the vector one. It's simply (v.transpose()*v).trace(). This is a more general dot product, but notice taking the trace will exactly "extract" the scalar from the 1x1 matrix.
Otherwise, this operation is already defined as the dot product (unsurprisingly): v.dot(v).

Variable sized keyword arguments in Julia

I'm writing a convex solver, for concreteness' sake assume it's solving ordinary least squares: find x that minimizes ||b-Ax||^2. So my function call would look like
x = optim(A, b)
I would like to be able to use warm-starts when they are useful, to provide a good initial guess at the solution. So something like
x = optim(A, b; w=some_starting_value)
My problem is that if I want to use a default value, some_starting_value needs to be of length equal to the number of columns in A, which is chosen by the user. In R it's possible to do something like
x = optim(A, b; w=ncols(A))
Does any similar functionality exist in Julia? My current solution is to do something like
x = optim(A, b; w=0)
and then check if w != 0 and set it to be the right size vector inside the optim function. But that seems hacky and (I assume) messes with type stability.
Is there a clean way to specify a keyword argument whose size depends on a required argument?
Edit
It looks like something like
function foo{T<:Real}(A::Array{T,2}; w=zeros(T,size(x,2)))
println("$x")
println("$y")
end
will do the trick.
It appears that default parameters in Julia can be expressions containing the values of the other parameters:
julia> a(x, y=2*x) = println("$x, $y")
a (generic function with 2 methods)
julia> a(10)
10, 20
Additionally the default parameter expressions can make calls to other functions:
julia> b(x) = sqrt(x)
b (generic function with 1 method)
julia> a(x, y=b(x)) = println("$x, $y")
a (generic function with 2 methods)
julia> a(100)
100, 10.0

scala breeze multiply matrix by transpose

I want to multiply two matrices. A * B works just fine. But what I really want is A.t * B. But after transposing A, the result becomes Transpose[Matrix[Double]] instead of Matrix[Double]. As a result the operation is rejected by the compiler. However, mathematically, the transpose of a matrix is another matrix, and it should be perfectly ok to multiply that by another matrix. How is this properly done in breeze?
A.t.asInstanceOf[DenseMatrix[Double]] did the trick.
I had a similar problem when I was using a plain Matrix type in Breeze, for example something like this:
def buildMatrix(): Matrix[Double] = {
DenseMatrix((1.0, 2.0, 3.0), (4.0, 5.0, 6.0))
}
val m = buildMatrix()
val t = m.t
m * t
gives me the compiler error Error:(13, 69) could not find implicit value for parameter op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.Matrix[Double],breeze.linalg.Transpose[breeze.linalg.Matrix[Double]],That]
But if I make sure that the matrix I'm transposing is a DenseMatrix, like this:
val m = buildMatrix().toDenseMatrix
Then the * operator works fine.

Matrix valued undefined functions in SymPy

I'm looking for a possibility to specify matrix quantities that depend on a variables. For scalars that works as follows, using undefined functions:
from sympy import *
x = Function('f')(t)
diff(x,t)
For Matrix Symbols like
x = MatrixSymbol('x',3,3)
i cannot find an equivalent. There is
i,j = Symbols('i j')
x = FunctionMatrix(6,1,Lambda((i,j),f))
but this is not what i need as you need to specify the contents of the matrix. The context is that i have equations
which should be derived in time and contain matrix valued elements.
I cannot deal with the elements of the matrices one by one.
Thanks!
I'm not sure about what you want, but I think you want to make a Matrix with differentiable elements. In that case, see if this works for you.
Create a matrix with function elements:
X = sym.FunctionMatrix(6,1,lambda i,j:sym.Function("x_%d%d" % (i,j))(t))
M = sym.Matrix(X)
M.diff(t)
This results in
Matrix([
[Derivative(x_00(t), t)],
[Derivative(x_10(t), t)],
[Derivative(x_20(t), t)],
[Derivative(x_30(t), t)],
[Derivative(x_40(t), t)],
[Derivative(x_50(t), t)]])
You may then replace stuff as you need.
Also, it may be preferrable if you populate the matrix with the expressions you need before differentiating. Leaving them as undefined functions may make it harder for you to simplify after substitution.

Please explain this code in Mathematica that creates a heat / intensity map

Graphics#Flatten[Table[
(*colors, dont mind*)
{ColorData["CMYKColors"][(a[[r, t]] - .000007)/(.0003 - 0.000007)],
(*point size, dont mind*)
PointSize[1/Sqrt[r]/10],
(*Coordinates for your points "a" is your data matrix *)
Point[
{(rr =Log[.025 + (.58 - .25)/64 r]) Cos#(tt = t 5 Degree),
rr Sin#tt}]
} &#
(*values for the iteration*)
, {r, 7, 64}, {t, 1, 72}], 1]
(*Rotation, dont mind*)
/. gg : Graphics[___] :> Rotate[gg, Pi/2]
Okay, I'll bite. First, Mathematica allows functions to be applied via one of several forms: standard form - f[x], prefix form - f # x, postfix form - f // x, and infix form - x ~ f ~ y. Belisarius's code uses both standard and prefix form.
So, let's look at the outermost functions first: Graphics # x /. gg : Graphics[___]:> Rotate[gg,Pi/2], where x is everything inside of Flatten. Essentially, what this does is create a Graphics object from x and using a named pattern (gg : Graphics[___]) rotates the resulting Graphics object by 90 degrees.
Now, to create a Graphics object, we need to supply a bunch of primitives and this is in the form of a nested list, where each sublist describes some element. This is done via the Table command which has the form: Table[ expr, iterators ]. Iterators can have several forms, but here they both have the form {var, min, max}, and since they lack a 4th term, they take on each value between min and max in integer steps. So, our iterators are {r, 7, 64} and {t, 1, 72}, and expr is evaluated for each value that they take on. Since, we have two iterators this produces a matrix, which would confuse Graphics, so we using Flatten[ Table[ ... ], 1] we take every element of the matrix and put it into a simple list.
Each element that Table produces is simply: color (ColorData), point size (PointSize), and point location (Point). So, with Flatten, we have created the following:
Graphics[{{color, point size, point}, {color, point size, point}, ... }]
The color generation is taken from the data, and it assumes that the data has been put into a list called a. The individual elements of a are accessed through the Part construct: [[]]. On the surface, the ColorData construct is a little odd, but it can be read as ColorData["CMYKColors"] returns a ColorDataFunction that produces a CMYK color value when a value between 0 and 1 is supplied. That is why the data from a is scaled the way it is.
The point size is generated from the radial coordinate. You'd expect with 1/Sqrt[r] the point size should be getting smaller as r increases, but the Log inverts the scale.
Similarly, the point location is produced from the radial and angular (t) variables, but Point only accepts them in {x,y} form, so he needed to convert them. Two odd constructs occur in the transformation from {r,t} to {x,y}: both rr and tt are Set (=) while calculating x allowing them to be used when calculating y. Also, the term t 5 Degree lets Mathematica know that the angle is in degrees, not radians. Additionally, as written, there is a bug: immediately following the closing }, the terms & and # should not be there.
Does that help?

Resources