#cast [M][N]f64 to [][]f64

1 messages · Page 1 of 1 (latest)

stiff ocean
#

what's the proper way to cast to slice for multidimensional arrays?

pub const Matrix2 = struct {
    I: usize, 
    J: usize,
    M: [][]f32,
    allocator: ?std.mem.Allocator,
}
...
var values = [5][3]f32{
        [_]f32{23.0, 16.0, 18.0},
        [_]f32{21.0, 23.0, 22.0},
        [_]f32{24.0, 20.0, 25.0},
        [_]f32{17.0, 21.0, 21.0},
        [_]f32{19.0, 18.0, 20.0},        
    };
    var matrix = Matrix2{ .I = 5, .J = 3, .M = &values };

I get an error
error: expected type '[][]f32', found '*[5][3]f32'
var matrix = Matrix2{ .I = 5, .J = 3, .M = &values };
^~~~~~~
src/anova_tests.zig:16:48: note: pointer type child '[3]f32' cannot cast into pointer type child '[]f32'

round goblet
#

not in that way. The memory layout of [][n]T and [][]T are entirely different

#

in the former, the values are all entirely consecutive in memory; in the latter, you have a slice of pointers, each of which refer to a section of values

#

what you could do is something like

var vals: [values.len][]f32 = undefined;
for (vals) |*elem, i| elem.* = &values[i];
var matrix = Matrix2{ .I = 5, .J = 3, .M = &vals };
#

but note that it's not really "casting", it's creating a new value that contains pointers to the original value, which is then pointed to by your slice

stiff ocean
#
pub const Matrix = struct {    
    I: usize,
    J: usize,
    M: []f32,
    allocator: ?std.mem.Allocator = null,   

    pub inline fn get_x(matrix: Matrix, i: usize, j: usize) f32 {
        return matrix.M[i * matrix.J + j];
    }

something like that would be better to create some matrix strucs?
P.S I also want to have a 3D and 4D Matrix

round goblet
#

sure, that seems pretty reasonable. Though I would just go ahead and omit the allocator field if it's a general matrix structure. Would let the user of the struct worry about that - simpler that way