diff --git a/src/feature_selection.odin b/src/feature_selection.odin index c22422b..79cdf6a 100644 --- a/src/feature_selection.odin +++ b/src/feature_selection.odin @@ -7,6 +7,7 @@ import "core:fmt" import "core:math" import "core:os" import "core:strconv" +import "base:runtime" NUMBER_OF_FEATURES :: 100 DATASET_ROWS :: 1994 @@ -23,7 +24,8 @@ Feature_State :: struct { X_train: [][]f64, X_test: [][]f64, y_train: []f64, - y_test: []f64 + y_test: []f64, + selected_indices_buffer: [NUMBER_OF_FEATURES]int, } feature_state: Feature_State @@ -96,6 +98,12 @@ split_dataset :: proc() { } fitness_features :: proc(chrom: Chromosome) -> f64 { + temp_arena: runtime.Arena + defer runtime.arena_destroy(&temp_arena) + temp_allocator := runtime.arena_allocator(&temp_arena) + + context.allocator = temp_allocator + X_train_selected := select_features(feature_state.X_train, chrom) X_test_selected := select_features(feature_state.X_test, chrom) @@ -103,46 +111,35 @@ fitness_features :: proc(chrom: Chromosome) -> f64 { return math.F64_MAX } - defer { - for row in X_train_selected {delete(row)} - for row in X_test_selected {delete(row)} - delete(X_train_selected) - delete(X_test_selected) - } - beta := train_linear_regression(X_train_selected, feature_state.y_train) - defer delete(beta) - predictions := predict(X_test_selected, beta) - defer delete(predictions) return rmse(predictions, feature_state.y_test) } // Select columns (features) based on chromosome -select_features :: proc(X: [][]f64, chrom: Chromosome) -> [][]f64 { - selected_indices := make([dynamic]int) - defer delete(selected_indices) - +select_features :: proc(X: [][]f64, chrom: Chromosome, allocator := context.allocator) -> [][]f64 { + // Count selected features inline + n_selected := 0 for i in 0 ..< bit_array.len(chrom) { if bit_array.get(chrom, i) { - append(&selected_indices, i) + feature_state.selected_indices_buffer[n_selected] = i + n_selected += 1 } } - if len(selected_indices) == 0 { + if n_selected == 0 { return nil } n_rows := len(X) - n_features := len(selected_indices) - result := make([][]f64, n_rows) + // Single allocation for all rows + result := make([][]f64, n_rows, allocator) for i in 0 ..< n_rows { - result[i] = make([]f64, n_features) - for j in 0 ..< n_features { - feat_idx := selected_indices[j] - result[i][j] = X[i][feat_idx] + result[i] = make([]f64, n_selected, allocator) + for j in 0 ..< n_selected { + result[i][j] = X[i][feature_state.selected_indices_buffer[j]] } }