From 9729fe6dcbc6bece1322d5a60e2784ac57085d26 Mon Sep 17 00:00:00 2001 From: omicron Date: Wed, 21 May 2025 23:04:00 +0200 Subject: [PATCH] Add matrix.CreateFromSlice function --- matrix/matrix.go | 27 +++++++++++++++++++++++++++ matrix/matrix_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/matrix/matrix.go b/matrix/matrix.go index 90d02e0..5dd59bd 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -54,6 +54,33 @@ func Create[T Number](rows, cols int) *Matrix[T] { } } +// Creates a new matrix from a given 2D slice of values. The first index of the +// slice denotes the rows and the second index denotes the columns. Returns the +// newly created matrix. +// +// Panics with ErrIncompatibleDataDimensions if any of the lengths are 0 or if +// not all rows have the same length. +func CreateFromSlice[T Number](values [][]T) *Matrix[T] { + rows := len(values) + if rows == 0 { + panic(ErrInvalidDimensions) + } + cols := len(values[0]) + if cols == 0 { + panic(ErrInvalidDimensions) + } + + m := Create[T](rows, cols) + for i := range rows { + if len(values[i]) != cols { + panic(ErrIncompatibleDataDimensions) + } + copy(m.values[i], values[i]) + } + + return m +} + // Creates a new matrix of a given size and sets the values from the given // slice. The values are used to fill the matrix left to right and top to // bottom. Returns the newly created matrix. diff --git a/matrix/matrix_test.go b/matrix/matrix_test.go index 4b06d6c..22782da 100644 --- a/matrix/matrix_test.go +++ b/matrix/matrix_test.go @@ -55,6 +55,41 @@ func TestCreate(t *testing.T) { }) } +func TestCreateFromSlice(t *testing.T) { + m := matrix.CreateFromSlice([][]int{ + {1, 2, 3}, + {4, 5, 6}, + }) + assert.NotNil(t, m) + + assert.Equal(t, 2, m.Rows()) + assert.Equal(t, 3, m.Cols()) + + assert.Equal(t, 1, m.Get(0, 0)) + assert.Equal(t, 2, m.Get(0, 1)) + assert.Equal(t, 3, m.Get(0, 2)) + assert.Equal(t, 4, m.Get(1, 0)) + assert.Equal(t, 5, m.Get(1, 1)) + assert.Equal(t, 6, m.Get(1, 2)) + + assert.PanicsWithValue(t, matrix.ErrInvalidDimensions, func() { + matrix.CreateFromSlice([][]int{}) + }) + + assert.PanicsWithValue(t, matrix.ErrInvalidDimensions, func() { + matrix.CreateFromSlice([][]int{ + {}, + }) + }) + + assert.PanicsWithValue(t, matrix.ErrIncompatibleDataDimensions, func() { + matrix.CreateFromSlice([][]int{ + {1, 2, 3}, + {4, 5}, + }) + }) +} + func TestCreateFromFlatSlice(t *testing.T) { m := matrix.CreateFromFlatSlice(2, 3, []int{1, 2, 3, 4, 5, 6}) assert.NotNil(t, m)